2013-10-18 41 views
12

W ramach szerszego programu, nad którym pracuję, skończyłem z tablicami obiektów z ciągami, współrzędnymi 3D i itd., Wszystkie pomieszane. Wiem, że tablice obiektów mogą nie być bardzo popularne w porównaniu do tablic strukturalnych, ale mam nadzieję, że uda mi się obejść to bez zmiany wielu kodów.Jak przekonwertować tablicę 2D Numpy z dtypem obiektu na zwykłą tablicę 2D z pływającymi obiektami?

Załóżmy każdy wiersz mojej tablicy obj_array (z N wierszy) ma format

Single entry/object of obj_array: ['NAME',[10.0,20.0,30.0],....] 

Teraz próbuję załadować tego obiektu tablicę i pokroić 3D koordynować klocek. Do tej pory wszystko działa dobrze, po prostu pytaj, powiedzmy.

obj_array[:,[1,2,3]] 

Jednak wynik jest również tablicę obiekt i będę obliczu problemu, ponieważ chcę, aby utworzyć 2D tablicę pływaków z:

size [N,3] of N rows and 3 entries of X,Y,Z coordinates 

Do tej pory mam zapętlenie nad rzędami i przypisanie każdego przejdź do rzędu docelowej dwuwymiarowej macierzy flot, aby ominąć problem. Zastanawiam się, czy istnieje lepszy sposób z narzędziami do konwersji w tablicy numpy? Próbowałem kilku rzeczy i nie mogłem tego obejść.

Centers = np.zeros([N,3]) 

for row in range(obj_array.shape[0]): 
    Centers[row,:] = obj_array[row,1] 

Dzięki

+0

Czy możesz pokazać prosty przykładowy kod - jak wyglądają oryginalne dane i jak wygląda twój kod konwersji? Ułatwi to komuś udzielenie odpowiedniej porady. – Floris

Odpowiedz

8

Nasty mały problem ... I zostały wygłupiać z tym przykładzie zabawki:

>>> arr = np.array([['one', [1, 2, 3]],['two', [4, 5, 6]]], dtype=np.object) 
>>> arr 
array([['one', [1, 2, 3]], 
     ['two', [4, 5, 6]]], dtype=object) 

Moje pierwsze przypuszczenie było:

>>> np.array(arr[:, 1]) 
array([[1, 2, 3], [4, 5, 6]], dtype=object) 

ale utrzymuje Dtyp object, więc może wtedy:

>>> np.array(arr[:, 1], dtype=np.float) 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
ValueError: setting an array element with a sequence. 

Można normalnie to obejść w następujący sposób:

>>> np.array(arr[:, 1], dtype=[('', np.float)]*3).view(np.float).reshape(-1, 3) 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
TypeError: expected a readable buffer object 

nie tutaj chociaż, który był rodzajem zastanawiające. Widocznie to jest fakt, że obiekty w macierzy są listy, które rzuca tę opcję, jako zastępujący list z krotek działa:

>>> np.array([tuple(j) for j in arr[:, 1]], 
...   dtype=[('', np.float)]*3).view(np.float).reshape(-1, 3) 
array([[ 1., 2., 3.], 
     [ 4., 5., 6.]]) 

Ponieważ nie wydaje się być dowolny całkowicie zadowalającego rozwiązania, najłatwiej jest prawdopodobnie aby przejść z:

>>> np.array(list(arr[:, 1]), dtype=np.float) 
array([[ 1., 2., 3.], 
     [ 4., 5., 6.]]) 

chociaż to nie będzie bardzo wydajny, chyba lepiej iść z czymś takim:

>>> np.fromiter((tuple(j) for j in arr[:, 1]), dtype=[('', np.float)]*3, 
...    count=len(arr)).view(np.float).reshape(-1, 3) 
array([[ 1., 2., 3.], 
     [ 4., 5., 6.]]) 
1

Możesz użyć zorganizowanego arr ay, więc jeśli chcesz uzyskać dostęp do nazw i wartości niezależnie, możesz to łatwo zrobić.W tym przykładzie, istnieją dwa punkty danych:

x = zeros(2, dtype=[('name','S10'), ('value','f4',(3,))]) 
x[0][0]='item1' 
x[1][0]='item2' 
y1=x['name'] 
y2=x['value'] 

wynik:

>>> y1 
array(['item1', 'item2'], 
     dtype='|S10') 
>>> y2 
array([[ 0., 0., 0.], 
     [ 0., 0., 0.]], dtype=float32) 

Zobacz więcej szczegółów: http://docs.scipy.org/doc/numpy/user/basics.rec.html

3

Bazując na przykład zabawek Jaime myślę, że można to zrobić w bardzo prosty sposób za pomocą np.vstack():

arr = np.array([['one', [1, 2, 3]],['two', [4, 5, 6]]], dtype=np.object) 
float_arr = np.vstack(arr[:, 1]).astype(np.float) 

To będzie ork bez względu na to, czy elementy "numeryczne" w twojej tablicy obiektów to tablice, listy lub krotki z liczbami 1D.

1

Działa to znakomicie przy pracy z tablicą arr i konwertowaniem z obiektu na tablicę zmiennych. Przetwarzanie liczb jest niezwykle łatwe po. Dzięki za ten ostatni post !!!! I tylko zmodyfikowany go o dowolnej wielkości DataFrame:

float_arr = np.vstack(arr[:, :]).astype(np.float) 
+0

To jest bardziej komentarz niż odpowiedź. Czy dotyczy to odpowiedzi ali_m? – jogo

0

Jest to sposób szybszy, aby po prostu zamienić tablicę obiektów do tablicy pływaka NumPy: arr=np.array(arr, dtype=[('O', np.float)]).astype(np.float) - stamtąd bez pętli, wskaźnik po prostu jak można normalnie zrobić na tablicy NumPy. Musiałbyś to zrobić w porcjach, ale z różnymi typami danych: arr[:, 1], arr[:,2] itd. Miał ten sam problem z krotką NumPy zwróconą z funkcji DLL C++ - konwersja dla elementów 17M zajmuje < 2s.

+0

Jeśli ktokolwiek faktycznie wypróbował to rozwiązanie powyżej i wyprofilował go, nie zostałby on odrzucony. – Matt

0

Ten problem zwykle występuje, gdy masz zestaw danych z różnymi typami, zwykle datami w pierwszej kolumnie.

Co mam zrobić, to przechowywać kolumnę daty w innej zmiennej; i prześlij resztę "X macierzy funkcji" do X. Więc mam na przykład daty i X.

Potem zastosować konwersję do macierzy X jak:

X = np.array(list(X[:,:]), dtype=np.float)

nadzieję pomóc!