Die kurze Antwort ist, können Sie einen der 52 Buchstaben (oben und unten) verwenden. Das sind alle Buchstaben in der englischen Sprache. Alle feineren Achsennamen müssen auf diesen 52 oder einem äquivalenten Zahlensatz abgebildet werden. Praktisch gesprochen wollen Sie einen Bruchteil dieser 52 in einem beliebigen einsum
Anruf verwenden.
@kennytm
schlägt die alternative Eingabesyntax. Ein paar Stichproben deuten darauf hin, dass dies keine Lösung ist. 26 ist immer noch das praktische Limit (trotz der verdächtigen Fehlermeldungen).
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]
Ich bin nicht ganz sicher, warum Sie mehr als 52 Buchstaben (Groß- und Kleinschreibung) benötigen, aber ich bin sicher, Sie brauchen eine Art von Mapping zu tun. Sie möchten keinen einsum
String mit mehr als 52 Achsen auf einmal schreiben. Der resultierende Iterator wäre zu groß (für Speicher oder Zeit).
Ich bin eine Art von Abbildungsfunktion abbildet, die als verwendet werden können:
astr = foo(A.names, B.names)
# foo(['i','j','k'],['j','k','l','m'])
# foo(['a1','a2','a3'],['a2','a3','b4','b5'])
np.einsum(astr, A, B)
https://github.com/hpaulj/numpy-einsum/blob/master/einsum_py.py
ist eine Python-Version von einsum
. Grob gesagt analysiert einsum
die Indexzeichenfolge und erstellt eine op_axes
Liste, die in np.nditer
verwendet werden kann, um die erforderliche Berechnung der Summe der Produkte einzurichten. Mit diesem Code kann ich sehen, wie die Übersetzung fertig ist:
Von einem Beispiel im __name__
Block:
label_str, op_axes = parse_subscripts('ik,kj->ij', Labels([A.ndim,B.ndim]))
print op_axes
# [[0, -1, 1], [-1, 1, 0], [0, 1, -1]] fine
# map (4,newaxis,3)(newaxis,3,2)->(4,2,newaxis)
print sum_of_prod([A,B],op_axes)
Ihr Beispiel mit vollem Diagnoseausgang ist
In [275]: einsum_py.parse_subscripts('ijk,jklm->ijklm',einsum_py.Labels([3,4]))
jklm
{'counts': {105: 1, 106: 2, 107: 2, 108: 1, 109: 1},
'strides': [],
'num_labels': 5,
'min_label': 105,
'nop': 2,
'ndims': [3, 4],
'ndim_broadcast': 0,
'shapes': [],
'max_label': 109}
[('ijk', [105, 106, 107], 'NONE'),
('jklm', [106, 107, 108, 109], 'NONE')]
('ijklm', [105, 106, 107, 108, 109], 'NONE')
iter labels: [105, 106, 107, 108, 109],'ijklm'
op_axes [[0, 1, 2, -1, -1], [-1, 0, 1, 2, 3], [0, 1, 2, 3, 4]]
Out[275]:
(<einsum_py.Labels at 0xb4f80cac>,
[[0, 1, 2, -1, -1], [-1, 0, 1, 2, 3], [0, 1, 2, 3, 4]])
Mit 'ajk,jkzZ->ajkzZ'
Änderungen Etiketten, aber Ergebnisse in der gleichen op_axes
.
Hier ist ein erster Entwurf einer Übersetzungsfunktion. Es sollte für jede Liste von Listen (von hashable Artikel) arbeiten:
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)
Die Verwendung von set
Indexobjekte abzubilden bedeutet, dass die endgültige Indizierung Zeichen ungeordnete sind. Solange Sie die RHS angeben, die kein Problem sein sollte. Auch ich ignorierte ellipsis
.
=================
Die Liste Version von einsum
Eingabe in den Index String-Version in einsum_list_to_subscripts()
(in numpy/core/src/multiarray/multiarraymodule.c
) umgewandelt wird. Es ersetzt ELLIPSIS
durch '...'. Es wurde die Fehlermeldung [0,52] ausgelöst, wenn (s < 0 || s > 2*26)
s
eine Nummer in einer dieser Unterlisten ist. Und wandelt s
bespannen mit
if (s < 26) {
subscripts[subindex++] = 'A' + s;
}
else {
subscripts[subindex++] = 'a' + s;
Aber es sieht aus wie der zweite Fall nicht funktioniert; Ich bekomme Fehler wie für 26.
ValueError: invalid subscript '{' in einstein sum subscripts string, subscripts must be letters
Das 'a'+s
ist falsch, wenn 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'
Das 'a'+s
ist falsch; ist sein sollte:
In [436]: ''.join([chr(ord('a')+i-26) for i in range(26,52)])
Out[436]: 'abcdefghijklmnopqrstuvwxyz'
I eingereicht https://github.com/numpy/numpy/issues/7741
Die Existenz dieses Fehlers nach all dieser Zeit zeigt an, dass das sublist Format nicht üblich ist, und dass in dieser Liste eine große Anzahl verwendet, ist noch seltener.
Sie können sie wahrscheinlich zu einem * fetten Array * stapeln? – Divakar
@Divakar Entschuldigung, was meinst du damit? – akxlr
Vergiss den vorherigen Kommentar. Meinst du 26 Dimensionen oder Variablen? Wenn es nur um Variablen geht, dann hat das nichts mit'Einsum' zu tun, oder? Diese "ijk" usw.repräsentieren die Dimensionen, während 'A' der Variablenname ist. Sie können immer mehr Variablen mit Namen wie 'AA', 'A2' usw. haben. – Divakar