2016-11-18 11 views
7

Mam tablicę 3D numpy i chcę tylko unikalne podwarstwy 2D.Unikalna podrzędna 2D Numpy

Wejście:

[[[ 1 2] 
    [ 3 4]] 

[[ 5 6] 
    [ 7 8]] 

[[ 9 10] 
    [11 12]] 

[[ 5 6] 
    [ 7 8]]] 

wyjściowa:

[[[ 1 2] 
    [ 3 4]] 

[[ 5 6] 
    [ 7 8]] 

[[ 9 10] 
    [11 12]]] 

Próbowałem przekonwertować sub-macierzy do łańcucha (metoda toString()), a następnie użyć np.unique, ale po przekształcić do numpy tablicy, usunęło ostatnie bajty \ x00, więc nie mogę go przekształcić za pomocą np.fromstring().

Przykład:

import numpy as np 
a = np.array([[[1,2],[3,4]],[[5,6],[7,8]],[[9,10],[11,12]],[[5,6],[7,8]]]) 
b = [x.tostring() for x in a] 
print(b) 
c = np.array(b) 
print(c) 
print(np.array([np.fromstring(x) for x in c])) 

wyjściowa:

[b'\x01\x00\x00\x00\x02\x00\x00\x00\x03\x00\x00\x00\x04\x00\x00\x00', b'\x05\x00\x00\x00\x06\x00\x00\x00\x07\x00\x00\x00\x08\x00\x00\x00', b'\t\x00\x00\x00\n\x00\x00\x00\x0b\x00\x00\x00\x0c\x00\x00\x00', b'\x05\x00\x00\x00\x06\x00\x00\x00\x07\x00\x00\x00\x08\x00\x00\x00'] 
[b'\x01\x00\x00\x00\x02\x00\x00\x00\x03\x00\x00\x00\x04' 
b'\x05\x00\x00\x00\x06\x00\x00\x00\x07\x00\x00\x00\x08' 
b'\t\x00\x00\x00\n\x00\x00\x00\x0b\x00\x00\x00\x0c' 
b'\x05\x00\x00\x00\x06\x00\x00\x00\x07\x00\x00\x00\x08'] 

--------------------------------------------------------------------------- 
ValueError        Traceback (most recent call last) 
<ipython-input-86-6772b096689f> in <module>() 
     5 c = np.array(b) 
     6 print(c) 
----> 7 print(np.array([np.fromstring(x) for x in c])) 

<ipython-input-86-6772b096689f> in <listcomp>(.0) 
     5 c = np.array(b) 
     6 print(c) 
----> 7 print(np.array([np.fromstring(x) for x in c])) 

ValueError: string size must be a multiple of element size 

Próbowałem też pogląd, ale ja naprawdę nie wiem, jak go używać. Czy możesz mi pomóc?

+1

Jest to [ nowa funkcja] (https://github.com/numpy/numpy/pull/7742) w nadchodzącym 1.13, jako 'np.unique (a, axis = 0)'. Możesz po prostu skopiować nową implementację i użyć jej w kodzie, ponieważ 1.13 nie jest jeszcze wypuszczony. – Eric

Odpowiedz

3

Korzystanie @Jaime's post, aby rozwiązać nasz przypadek znalezienia unikalne subarrays 2D, wpadłem na to rozwiązanie, które w zasadzie dodaje dopasowania kształtu do etapu view -

def unique2D_subarray(a): 
    dtype1 = np.dtype((np.void, a.dtype.itemsize * np.prod(a.shape[1:]))) 
    b = np.ascontiguousarray(a.reshape(a.shape[0],-1)).view(dtype1) 
    return a[np.unique(b, return_index=1)[1]] 

run Sample -

In [62]: a 
Out[62]: 
array([[[ 1, 2], 
     [ 3, 4]], 

     [[ 5, 6], 
     [ 7, 8]], 

     [[ 9, 10], 
     [11, 12]], 

     [[ 5, 6], 
     [ 7, 8]]]) 

In [63]: unique2D_subarray(a) 
Out[63]: 
array([[[ 1, 2], 
     [ 3, 4]], 

     [[ 5, 6], 
     [ 7, 8]], 

     [[ 9, 10], 
     [11, 12]]]) 
+0

Dziękuję za odpowiedź! Więc jeśli dobrze zrozumiałe dtype określa sekwencję bajtów (nie jest to dowolny typ) rozmiaru a.dtype.itemsize * rozmiar subarray? Potrzebna jest ciągła tablica, ponieważ dtype jest określone jako ciąg bajtów? Bardzo mi przykro z powodu podwójnego pytania, ale nie rozumiem z postu @ Jaime. –

+0

@ Peťan Masz rację co do pierwszej części. W drugiej części o konieczności bycia "przyległym". Również nie jestem do końca jasny. Być może warto opublikować komentarz do tego wpisu. Jeśli muszę zgadywać, powiedziałbym, że twoja druga część wydaje się logiczna, ale tak, te dwie części są ze sobą powiązane. – Divakar

1

Jednym rozwiązaniem byłoby użyć zestawu śledzić których sub tablice zostały widziany:

seen = set([]) 
new_a = [] 

for j in a: 
    f = tuple(list(j.flatten())) 
    if f not in seen: 
     new_a.append(j) 
     seen.add(f) 

print np.array(new_a) 

lub przy użyciu numpy tylko:

print np.unique(a).reshape((len(unique)/4, 2, 2)) 

>>> [[[ 1 2] 
     [ 3 4]] 

    [[ 5 6] 
     [ 7 8]] 

    [[ 9 10] 
     [11 12]]] 
+2

Tak więc [ta odpowiedź] (http://stackoverflow.com/a/22941699/102441) od dupe skomentował powyżej – Eric

+0

Utracisz kolejność pod-tablic z tą odpowiedzią – kezzos

+0

Jeśli ktoś właśnie skopiował tablicę do zbioru, a następnie z powrotem do tablicy, kolejność zostałaby utracona, to prawda, ale została wykonana w sposób, w jaki została wykonana w powyższym kodzie, kolejność wygrała " być zagubionym. –

1

Pakiet numpy_indexed (disclaimer: Jestem jego autor) jest przeznaczony do wykonywania takich operacji w wydajny i wektoryzowany sposób:

import numpy_indexed as npi 
npi.unique(a)