Konvertieren Sie das numpy-Array in ein Tupel

108

Hinweis: Dies erfordert die Umkehrung der üblichen Tupel-Array-Konvertierung.

Ich muss ein Argument als verschachteltes Tupel an eine (umschlossene c ++) Funktion übergeben. Zum Beispiel funktioniert das Folgende

X = MyFunction( ((2,2),(2,-2)) )

während die folgenden nicht

X = MyFunction( numpy.array(((2,2),(2,-2))) )
X = MyFunction( [[2,2],[2,-2]] )

Leider kommt mir das Argument, das ich verwenden möchte, als numpy Array vor. Dieses Array hat immer Dimensionen 2xN für einige N, die ziemlich groß sein können.

Gibt es eine einfache Möglichkeit, dies in ein Tupel umzuwandeln? Ich weiß, dass ich mich einfach durchschleifen und ein neues Tupel erstellen könnte, würde es aber vorziehen, wenn das numpy-Array einen guten Zugriff bietet.

Wenn es nicht so gut möglich ist, wie ich hoffe, was ist der schönste Weg, dies durch Schleifen zu tun, oder was auch immer?

Mike
quelle

Antworten:

156
>>> arr = numpy.array(((2,2),(2,-2)))
>>> tuple(map(tuple, arr))
((2, 2), (2, -2))
Niklas B.
quelle
29
Also für ein einfaches 1-D-Arraytuple(arr)
FindOutIslamNow
26

Hier ist eine Funktion, die das macht:

def totuple(a):
    try:
        return tuple(totuple(i) for i in a)
    except TypeError:
        return a

Und ein Beispiel:

>>> array = numpy.array(((2,2),(2,-2)))
>>> totuple(array)
((2, 2), (2, -2))
Bi Rico
quelle
1
Schöne Verallgemeinerung. Als Python-Neuling frage ich mich jedoch, ob es als guter Stil angesehen wird, Ausnahmen für eine Bedingung zu verwenden, die fast so häufig ist wie der nicht außergewöhnliche Zustand. Zumindest in c ++ wird die Flusskontrolle durch Ausnahmen normalerweise verpönt. Wäre es besser zu testen, ob type(a)==numpy.ndarray?
Mike
9
Dies ist in Python aufgrund des Konzepts von "duck-typing" und EAFT ziemlich häufig, mehr hier: docs.python.org/glossary.html#term-duck-typing . Der Vorteil dieses Ansatzes besteht darin, dass jede verschachtelte Sequenz in verschachtelte Tupel konvertiert wird, nicht nur in ein Array. Eine Sache, die ich hätte tun sollen, die ich behoben habe, ist anzugeben, welche Fehler vom Ausnahmeblock behandelt werden sollen.
Bi Rico
2
In C ++ sind Ausnahmen aus verschiedenen Gründen im Vergleich zu Bedingungen langsam. In Python sind sie in Bezug auf die Leistung ungefähr gleich - dies ist einer der Orte, an denen wir unsere C ++ - Intuitionen an der Tür überprüfen müssen.
dbn
8

Ich war nicht zufrieden, also habe ich das endlich benutzt:

>>> a=numpy.array([[1,2,3],[4,5,6]])
>>> a
array([[1, 2, 3],
       [4, 5, 6]])

>>> tuple(a.reshape(1, -1)[0])
(1, 2, 3, 4, 5, 6)

Ich weiß nicht, ob es schneller geht, aber es sieht effektiver aus;)

Ich hoffe, es hilft
quelle
3
Das war nicht die Form, die ich für das Tupel wollte.
Mike
5

Andere Option

tuple([tuple(row) for row in myarray])

Wenn Sie NumPy-Arrays an C ++ - Funktionen übergeben, möchten Sie möglicherweise auch Cython oder SWIG verwenden.

Greg von Winckel
quelle
Das wird nicht in Tupel umgewandelt. In eine Liste konvertieren?
Peter
Hast Du es versucht? Beim Ausführen wird ein Tupel erstellt. Beachten Sie, dass die zuletzt aufgerufene Funktion Tupel ist, das ein Tupel zurückgibt. Wenn Sie nur den [...] Teil ohne das äußere Tupel haben, erhalten Sie eine Liste der Tupel.
Greg von Winckel
Gibt es eine schnellere Methode?
Vicrobot
1
Sie können das Erstellen des Zwischenprodukts vermeiden, listindem Sie die eckigen Klammern weglassen, dhtuple(tuple(row) for row in myarray)
norok2
1

Wenn Sie lange Schnitte mögen, gibt es hier einen anderen Weg, Tupel (Tupel (a_m.tolist ()) für a_m in a)

from numpy import array
a = array([[1, 2],
           [3, 4]])
tuple(tuple(a_m.tolist()) for a_m in a )

Die Ausgabe ist ((1, 2), (3, 4))

Beachten Sie, dass nur (Tupel (a_m.tolist ()) für a_m in a) einen Generatorausdruck ergibt. Inspiriert von @ norok2s Kommentar zu Greg von Winckels Antwort

Tejas Shetty
quelle