2013-08-28 15 views
6

Mam dwie tablice, słownie:Ustal argumenty gdzie przecinają dwie tablice numpy w Pythonie

a, b = np.array([13., 14., 15., 32., 33.]), np.array([15., 16., 17., 33., 34., 47.]) 

Muszę znaleźć indeksy wszystkich elementów w które nie są obecne w b. W powyższym przykładzie wynik to:

[0, 1, 3] 

Ponieważ [0] A [1] i [3] są 13, 14 i 32, które nie są obecne w B. Zauważ, że nie chcę znać rzeczywistych wartości 13, 14 i 32. (W takim przypadku mógłbym użyć zestawu (a) .difference (set (b)). Interesuję się tylko wskaźnikami.

Jeśli to możliwe, odpowiedź powinna być "wektoryzowana", tzn. Nie należy używać pętli for.

+0

Czy to tylko zbieg okoliczności w tym przykładzie, że są one zarówno sortowane tablice? (jeśli są posortowane w rzeczywistej wersji twojego problemu, możesz nadużyć tej właściwości) – usethedeathstar

+0

Przepraszamy, użyłem posortowanych tablic, aby pomóc w czytaniu. Ale nadal jestem zainteresowany, aby usłyszeć, co zrobiłbyś z posortowanymi tablicami :) – astabada

+0

Cóż, niestandardowy algorytm może uzyskać jeszcze większą złożoność przez nadużywanie faktu, że są one sortowane, (nie do końca pewne, jaką złożoność uzyskasz w końcu , ale zakładam, że lepiej niż cokolwiek robisz, jeśli nie masz tej właściwości) – usethedeathstar

Odpowiedz

3

Można użyć np.in1d:

>>> np.arange(a.shape[0])[~np.in1d(a,b)].tolist() 
    [0, 1, 3] 
+0

+1 to wydaje się być najlepszym rozwiązaniem do tej pory ... –

1

Dość prosta, jeśli używasz pętle:

def difference_indices(a, b): 

    # Set to put the unique indices in 
    indices = [] 

    # So we know the index of the element of a that we're looking at 
    a_index = 0 

    for elem_a in a: 

     found_in_b = False 
     b_index = 0 

     # Loop until we find a match. If we reach the end of b without a match, the current 
     # a index should go in the indices list 
     while not found_in_b and b_index < len(b): 
      if elem_a == b[b_index]: found_in_b = True 
      b_index = b_index + 1 

     if not found_in_b: indices.append(a_index) 
     a_index = a_index + 1 

    return indices 

To powinno działać z listy zawierające dowolny jeden typ, tak długo jak są one tego samego typu, dla tego typu jest zdefiniowana funkcja __eq__.

Wykonanie tego bez pętli wymagałoby znajomości Pythona większego niż moje! Mam nadzieję, że jest to przydatne dla Ciebie.

2

Jest to dość proste, należy numpy.intersect1d obliczania elementów wspólnych między a i b, a następnie sprawdzić, które z tych elementów nie są w a użyciu numpy.in1d i wreszcie dostać swoją pozycję w tablicy przy użyciu numpy.argwhere.

>>> import numpy as np 
>>> a, b = np.array([13., 14., 15., 32., 33.]), np.array([15., 16., 17., 33., 34., 47.]) 
>>> np.argwhere(np.in1d(a, np.intersect1d(a,b)) == False) 
array([[0], 
    [1], 
    [3]]) 

Jeśli wolisz listę wystarczy dodać .flatten celu przekształcenia macierzy do wektora, a następnie zastosować .tolist, aby uzyskać listę:

>>> np.argwhere(np.in1d(a, np.intersect1d(a,b)) == False).flatten().tolist() 
[0, 1, 3] 
+0

Nie znałem żadnej z trzech metod. Wspaniały! – astabada