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?

Odpowiedzi:



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

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


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.


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

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.