2017-04-24 30 views
6

Mam prostą listę elementów i próbuję zrobić z tego structured array.Tworzenie tablicy strukturalnej z listy

to naiwne podejście kończy się niepowodzeniem:

y = np.array([1,2,3], dtype=[('y', float)]) 
TypeError: expected an object with a buffer interface 

Umieszczenie każdego elementu krotki działa:

# Manuel way 
y = np.array([(1,), (2,), (3,)], dtype=[('y', float)]) 
# Comprehension 
y = np.array([tuple((x,)) for x in [1,2,3]], dtype=[('y', float)]) 

Działa również jeśli utworzyć tablicę z listy pierwszy:

y = np.array(np.array([1,2,3]), dtype=[('y', float)]) 

Jestem trochę zdziwiony. Jak to działa, ale nie można było uporządkować rzeczy, gdy dostarczono prostą listę?

Jaki jest zalecany sposób? Utworzenie tego pośredniego array może nie mieć dużego wpływu na wydajność, ale czy nie jest to suboptymalne?

Jestem również zaskoczony, że to nie będzie działać:

# All lists 
y = np.array([[1,], [2,], [3,]], dtype=[('y', float)]) 
TypeError: expected an object with a buffer interface 
# All tuples 
y = np.array(((1,), (2,), (3,)), dtype=[('y', float)]) 
ValueError: size of tuple must match number of fields. 

Jestem nowy strukturyzowanych tablic i nie pamiętam numpy jest, że wybredna typów wejściowych. Musi być coś, czego mi brakuje.

+0

Ponieważ rzędy muszą być przypisane do korzystania krotki, ponieważ każdy element tablicy jest uporządkowany * struct *, więc nie ma jakiś związek typu danych. Alternatywą jest użycie bufora (dlatego działa 'np.array'). –

+0

To jest w pewnym stopniu udokumentowane [tutaj] (https://docs.scipy.org/doc/numpy/user/basics.rec.html#filling-structured-arrays) –

+0

W poprzednim paragrafie docs wspomniano: "Zauważ, że x jest utworzony z listą krotek. ". Ten styl wejściowy pasuje do stylu wyświetlania. Wolę podejście do rozumienia listy. Lub wypełnianie pola wstępnie przydzielonej tablicy za pomocą pola. – hpaulj

Odpowiedz

3

Szczegółowe informacje o tym, jak np.array obsługuje różne wejścia są pochowane w skompilowanym kodzie. Ponieważ wiele pytań dotyczących tworzenia tablic obiektów typu dtype może się okazać skomplikowane i mylące. Podstawowym modelem jest tworzenie wielowymiarowych tablic numerycznych z listy zagnieżdżonej.

np.array([[1,2,3],[4,5,6]]) 

Wdrażając tablice strukturyzowane, twórcy przyjęli tuple jako sposób odróżniania rekord z zagnieżdżonego tylko kolejny wymiar. Jest to widoczne na wyświetlaczu tablicy strukturalnej.

Jest to również wymagane przy definiowaniu tablicy strukturalnej, chociaż wymaganie list of tuples jest nieco ukryte w dokumentacji.

In [382]: dt=np.dtype([('y',int)]) 
In [383]: np.array(alist,dt) 

TypeError: a bytes-like object is required, not 'int' 

To jest komunikat o błędzie mojej wersji "1.12.0". Wygląda na to, że jest inaczej w twoim.

Jak zauważysz, zrozumienie listy może przekształcić listę gniazd w listę krotek.

In [384]: np.array([tuple(i) for i in alist],dt) 
Out[384]: 
array([(1,), (2,), (3,)], 
     dtype=[('y', '<i4')]) 

Odpowiadając na pytania typu SO, najczęściej stosuję takie podejście. Albo to albo iteracyjnie ustawiaj pola wcześniej przydzielonej tablicy (zwykle jest o wiele więcej rekordów niż pól, więc pętla nie jest droga).

Wygląda owijania tablicę w uporządkowany połączenia tablicy jest odpowiednikiem astype rozmowy:

In [385]: np.array(np.array(alist),dt) 
Out[385]: 
array([[(1,)], 
     [(2,)], 
     [(3,)]], 
     dtype=[('y', '<i4')]) 
In [386]: np.array(alist).astype(dt) 
Out[386]: 
array([[(1,)], 
     [(2,)], 
     [(3,)]], 
     dtype=[('y', '<i4')]) 

jednak zwrócić uwagę na zmiany w liczbie wymiarów. Lista krotek utworzyła tablicę (3,). Przetworzona macierz numeryczna astype przekształciła macierz numeryczną (3,1) w macierz strukturalną (3,1).

Część tego, co krotki mówią np.array jest - wstawienie podziału na wymiary tablicy i zapisanie "tutaj".Interpretuje

[(3,), (1,), (2,)] 
[record, record, record] 

gdzie jak automatyczne tłumaczenie [[1],[2],[3]] może produkować

[[record],[record],[record]] 

Gdy dtype jest numeryczne (non-zorganizowany) ignoruje rozróżnienie między listy i krotki

In [388]: np.array([tuple(i) for i in alist],int) 
Out[388]: 
array([[1], 
     [2], 
     [3]]) 

But gdy dtype jest złożone, twórcy zdecydowali się użyć warstwy krotki jako znaczącej informacji.


Rozważmy bardziej złożony zorganizowanego dtype

In [389]: dt1=np.dtype([('y',int,(2,))]) 
In [390]: np.ones((3,), dt1) 
Out[390]: 
array([([1, 1],), ([1, 1],), ([1, 1],)], 
     dtype=[('y', '<i4', (2,))]) 
In [391]: np.array([([1,2],),([3,4],)]) 
Out[391]: 
array([[[1, 2]], 

     [[3, 4]]]) 
In [392]: np.array([([1,2],),([3,4],)], dtype=dt1) 
Out[392]: 
array([([1, 2],), ([3, 4],)], 
     dtype=[('y', '<i4', (2,))]) 

wyświetlacza (i wejścia) ma wewnątrz krotki list w obrębie listy. A to dopiero początek

In [393]: dt1=np.dtype([('x',dt,(2,))]) 
In [394]: dt1 
Out[394]: dtype([('x', [('y', '<i4')], (2,))]) 
In [395]: np.ones((2,),dt1) 
Out[395]: 
array([([(1,), (1,)],), ([(1,), (1,)],)], 
     dtype=[('x', [('y', '<i4')], (2,))]) 

convert list of tuples to structured numpy array

+0

Dziękujemy za wyczerpującą odpowiedź. Teraz ma to więcej sensu. Byłem nieco zaskoczony, ponieważ z mojego skromnego doświadczenia wynikało, że numpy był "I'm-a-scientist-with-no-python-background-and-I-can-do-numpy" łatwy, z niewielkim zdziwieniem, i wydaje się manipulowanie uporządkowanymi tablicami wymaga znacznie więcej zabezpieczeń i zrozumienia tego, co dzieje się wewnątrz. –