In [258]: np.einsum(np.ones((2,3)),[0,20],np.ones((3,4)),[20,2],[0,2])
Out[258]:
array([[ 3., 3., 3., 3.],
[ 3., 3., 3., 3.]])
In [259]: np.einsum(np.ones((2,3)),[0,27],np.ones((3,4)),[27,2],[0,2])
-
ValueError Traceback (most recent call last)
<ipython-input-259-ea61c9e50d6a> in <module>()
> 1 np.einsum(np.ones((2,3)),[0,27],np.ones((3,4)),[27,2],[0,2])
ValueError: invalid subscript '|' in einstein sum subscripts string, subscripts must be letters
In [260]: np.einsum(np.ones((2,3)),[0,100],np.ones((3,4)),[100,2],[0,2])
-
ValueError Traceback (most recent call last)
<ipython-input-260-ebd9b4889388> in <module>()
> 1 np.einsum(np.ones((2,3)),[0,100],np.ones((3,4)),[100,2],[0,2])
ValueError: subscript is not within the valid range [0, 52]
def translate(ll):
mset=set()
for i in ll:
mset.update(i)
dd={k:v for v,k in enumerate(mset)}
x=[''.join([chr(dd[i]+97) for i in l]) for l in ll]
# ['cdb', 'dbea', 'cdbea']
y=','.join(x[:-1])+'->'+x[-1]
# 'cdb,dbea->cdbea'
In [377]: A=np.ones((3,1,2),int)
In [378]: B=np.ones((1,2,4,3),int)
In [380]: ll=[list(i) for i in ['ijk','jklm','ijklm']]
In [381]: y=translate(ll)
In [382]: y
Out[382]: 'cdb,dbea->cdbea'
In [383]: np.einsum(y,A,B).shape
Out[383]: (3, 1, 2, 4, 3)
einsum输入的列表版本被转换为einsum_list_to_subscripts()(在numpy/core/src/multiarray/multiarraymodule.c)中的下标字符串版本。它将ELLIPSIS替换为“…”。如果( s < 0 || s > 2*26),其中s是其中一个子列表中的一个数字,则它将引发[0,52]错误消息。并使用
if (s < 26) {
subscripts[subindex++] = 'A' + s;
}
else {
subscripts[subindex++] = 'a' + s;
但是看起来第二个案子不起作用了,我得到了26个这样的错误。在
ValueError: invalid subscript '{' in einstein sum subscripts string, subscripts must be letters
如果s>26,则{}是错误的:
In [424]: ''.join([chr(ord('A')+i) for i in range(0,26)])
Out[424]: 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
In [425]: ''.join([chr(ord('a')+i) for i in range(0,26)])
Out[425]: 'abcdefghijklmnopqrstuvwxyz'
In [435]: ''.join([chr(ord('a')+i) for i in range(26,52)])
Out[435]: '{|}~\x7f\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f\x90\x91\x92\x93\x94'
这'a'+s是错误的;应该是:
In [436]: ''.join([chr(ord('a')+i-26) for i in range(26,52)])
Out[436]: 'abcdefghijklmnopqrstuvwxyz'
简而言之,你可以使用52个字母中的任何一个(上下)。这是英语中所有的字母。任何更漂亮的坐标轴名称都必须映射到这52个坐标轴上,或是一组等效的数字。实际上,在任何一个
einsum
调用中,您都希望使用这52个值的一小部分。在@kennytm
建议使用替代输入语法。一些样本表明这不是一个解决方案。26仍然是实际限制(尽管有可疑的错误消息)。在我不太清楚为什么你需要超过52个字母(大写和小写),但我确定你需要做一些映射。您不希望一次使用超过52个轴编写
einsum
字符串。结果迭代器将太大(对于内存或时间)。在我在描绘一些映射函数,可以用作:
^{pr2}$https://github.com/hpaulj/numpy-einsum/blob/master/einsum_py.py
{cda>是Python的版本。粗略地说,
einsum
解析下标字符串,创建一个可以在np.nditer
中使用的op_axes
列表来设置所需的积和计算。通过这段代码,我可以了解翻译是如何完成的:从
__name__
块中的一个示例:您的示例,完整的诊断输出是
使用
'ajk,jkzZ->ajkzZ'
会更改标签,但会导致相同的op_axes
。在这是翻译功能的初稿。它应该适用于任何列表列表(哈希项):
使用
set
映射索引对象意味着最终的索引字符是无序的。只要你指定不应该成为问题的RHS。我也忽略了ellipsis
。在==============
einsum
输入的列表版本被转换为einsum_list_to_subscripts()
(在numpy/core/src/multiarray/multiarraymodule.c
)中的下标字符串版本。它将ELLIPSIS
替换为“…”。如果( s < 0 || s > 2*26)
,其中s
是其中一个子列表中的一个数字,则它将引发[0,52]错误消息。并使用但是看起来第二个案子不起作用了,我得到了26个这样的错误。在
如果}是错误的:
s>26
,则{这
'a'+s
是错误的;应该是:我提交了https://github.com/numpy/numpy/issues/7741
这个错误的存在表明子列表格式并不常见,并且在该列表中使用大数字的频率更低。在
如果您在示例中讨论的是字母
ijk
,并且有比可用的字母字符更多的字母,那么不,您不能这样做在einsum numpy代码here和{a2}中,numpy用^{} 逐个检查每个字符,似乎没有办法创建一个以上字符的名称。在
也许你可以用大写字母,但问题的主要答案是你不能有超过1个字符的轴的名称。在
您可以使用
einsum(op0, sublist0, op1, sublist1, ..., [sublistout])
形式,而不是i,j,ik->ijk
,API不限于52个轴*。这个详细的形式如何对应于ijk形式显示为in the documentation。在手术室
会写为
^{pr2}$(*注:实现仍然限于26个轴。请参见@hpaulj's answer和his bug report了解说明)
numpy例子中的等价物:
相关问题 更多 >
编程相关推荐