Konwertuj tablicę numpy na krotkę

108

Uwaga: jest to prośba o odwrócenie zwykłej konwersji krotki na tablicę.

Muszę przekazać argument do funkcji (opakowanej w c ++) jako zagnieżdżonej krotce. Na przykład działa następująca

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

podczas gdy poniższe nie

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

Niestety argument, którego chciałbym użyć, przychodzi do mnie jako tablica numpy. Ta tablica zawsze ma wymiary 2xN dla niektórych N, które mogą być dość duże.

Czy istnieje łatwy sposób przekształcenia tego w krotkę? Wiem, że mógłbym po prostu zapętlić, tworząc nową krotkę, ale wolałbym, aby był jakiś fajny dostęp, który zapewnia tablica numpy.

Jeśli nie można tego zrobić tak przyjemnie, jak mam nadzieję, jaki jest najpiękniejszy sposób na zrobienie tego przez zapętlenie, czy cokolwiek innego?

Mikrofon
źródło

Odpowiedzi:

157
>>> arr = numpy.array(((2,2),(2,-2)))
>>> tuple(map(tuple, arr))
((2, 2), (2, -2))
Niklas B.
źródło
29
A więc dla prostej tablicy 1-dtuple(arr)
FindOutIslamNow
26

Oto funkcja, która to zrobi:

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

I przykład:

>>> array = numpy.array(((2,2),(2,-2)))
>>> totuple(array)
((2, 2), (2, -2))
Bi Rico
źródło
1
Niezłe uogólnienie. Jednak jako nowicjusz w Pythonie zastanawiam się, czy za dobry styl uważa się używanie wyjątków dla warunku, który jest prawie tak powszechny, jak stan nietypowy. Przynajmniej w języku c ++ kontrola przepływu przez wyjątki jest zwykle źle widziana. Czy lepiej byłoby to sprawdzić type(a)==numpy.ndarray?
Mike
9
Jest to dość powszechne w Pythonie z powodu koncepcji "kaczego pisania" i EAFT, więcej tutaj: docs.python.org/glossary.html#term-duck-typing . Zaletą tego podejścia jest to, że konwertuje ono dowolną zagnieżdżoną sekwencję na zagnieżdżone krotki, a nie tylko tablicę. Jedną rzeczą, którą powinienem był zrobić, którą naprawiłem, jest określenie, które błędy mają być obsługiwane przez blok except.
Bi Rico,
3
W C ++ wyjątki są powolne w stosunku do warunków warunkowych z różnych powodów. W Pythonie są w przybliżeniu takie same pod względem wydajności - to jedno z miejsc, w których musimy sprawdzić nasze intuicje C ++ przy drzwiach.
dbn
8

Nie byłem zadowolony, więc w końcu skorzystałem z tego:

>>> 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)

Nie wiem, czy to szybsze, ale wygląda bardziej efektywnie;)

mając nadzieję, że to pomoże
źródło
3
To nie był kształt, którego chciałem dla krotki.
Mike
5

Inna opcja

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

Jeśli przekazujesz tablice NumPy do funkcji C ++, możesz również chcieć przyjrzeć się użyciu Cythona lub SWIG.

Greg von Winckel
źródło
To nie jest konwertowane na krotkę. Konwertuje na listę?
Peter
Próbowałeś tego? Kiedy wbiegam, tworzy krotkę. Zauważ, że ostatnia wywołana funkcja to krotka, która zwraca krotkę. Jeśli masz tylko część [...] bez zewnętrznej krotki, otrzymasz listę krotek.
Greg von Winckel
czy jest szybsza metoda?
Vicrobot
1
Możesz uniknąć tworzenia pośredniego list, pomijając nawiasy kwadratowe, np. Używająctuple(tuple(row) for row in myarray)
norok2
1

Jeśli lubisz długie cięcia, oto inny sposób krotki (krotka (a_m.tolist ()) dla a_m w a)

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

Dane wyjściowe to ((1, 2), (3, 4))

Zauważ, że tylko (tuple (a_m.tolist ()) for a_m in a) da wyrażenie generatora. Rodzaj inspiracji komentarzem @ norok2 do odpowiedzi Grega von Winckela

Tejas Shetty
źródło