2016-03-26 18 views
1

Ich habe zwei numpy Arrays a und b, mit zwanzig Millionen Elementen (Fließkommazahl). Wenn die Kombinationselemente dieser beiden Arrays gleich sind, nennen wir es Duplikat, das aus den beiden Arrays entfernt werden sollte. Zum BeispielEntfernen doppelte Elemente aus zwei numpy Arrays

a = numpy.array([1,3,6,3,7,8,3,2,9,10,14,6]) 
b = numpy.array([2,4,15,4,7,9,2,2,0,11,4,15]) 

Aus diesen beiden Arrays haben wir a[2]&b[2] die gleiche wie a[11]&b[11] ist, dann nennen wir es Element duplizieren, die entfernt werden sollen. Das gleiche wie a[1]&b[1] vs a[3]&b[3] Obwohl jedes Array selbst doppelte Elemente hat, werden sie nicht als doppelte Elemente behandelt. So möchte ich die zurückgegebenen Arrays zu sein:

a = numpy.array([1,3,6,7,8,3,2,9,10,14]) 
b = numpy.array([2,4,15,7,9,2,2,0,11,4]) 

Wer hat den klügsten Weg, um solche Reduktion zu implementieren?

+0

'b [a = b! ] 'und' a [a! = b] 'würde funktionieren? – Zero

+0

Ich habe versucht, es funktioniert nicht wie erwartet. –

+0

Ah, die Frage falsch gelesen, 'np.vstack ({Tupel (Zeile) für Zeile in np.column_stack ((a, b))})' sollte funktionieren, kann nicht geben Sie Ihre erste eindeutige Element Reihenfolge. – Zero

Antwort

2

Zuerst müssen Sie a und b packen Duplikate zu identifizieren. Wenn Werte positive ganze Zahlen (siehe bearbeiten in anderen Fällen), kann dies erreicht werden durch:

base=a.max()+1 
c=a+base*b 

Dann nur eindeutige Werte in c finden:

val,ind=np.unique(c,return_index=True) 

und rufen Sie die zugehörigen Werte in a und b.

ind.sort() 
print(a[ind]) 
print(b[ind]) 

für die Disparation des Duplikats.(Hier zwei):

[ 1 3 6 7 8 3 2 9 10 14] 
[ 2 4 15 7 9 2 2 0 11 4] 

EDIT

unabhängig vom Datentyp kann der c-Array vorgenommen werden folgen, Daten zu Bytes Verpackung:

ab=ascontiguousarray(vstack((a,b)).T) 
dtype = 'S'+str(2*a.itemsize) 
c=ab.view(dtype=dtype) 
+0

Danke. Die Array-Werte sind positiv, aber die Gleitkommazahl. –

+0

Ich habe einen allgemeineren Ansatz zur Verfügung gestellt. –

+0

Vielen Dank. Es klappt. Ihr Code ist prägnant, aber nicht so einfach, es zu bekommen ~~~ –

1

Dies wird in einem Durchgang durchgeführt, ohne für die resultierenden Arrays jeden zusätzlichen Speicher zu erfordern.

Paar bis die Elemente an jedem Index und iterieren sie. Verfolgen Sie, welche Paare bisher gesehen wurden und einen Zähler des Index der Arrays. Wenn ein neues Paar noch nie zuvor gesehen wurde, wird der Index um 1 erhöht und effektiv an den ursprünglichen Platz zurückgeschrieben. Bei einem doppelten Paar erhöht sich jedoch nicht der Index, wodurch effektiv jedes neue Paar um eine Position nach links verschoben wird. Am Ende halten Sie die erste index th Anzahl der Elemente, um die Arrays zu verkürzen.

import itertools as it 

def delete_duplicate_pairs(*arrays): 
    unique = set() 
    arrays = list(arrays) 
    n = range(len(arrays)) 
    index = 0 
    for pair in it.izip(*arrays): 
     if pair not in unique: 
      unique.add(pair) 
      for i in n: 
       arrays[i][index] = pair[i] 
      index += 1 
    return [a[:index] for a in arrays] 

Wenn Sie auf Python sind 2, erstellt zip() die Liste von Paaren vorne. Wenn Sie viele Elemente in Ihren Arrays haben, ist es effizienter, itertools.izip() zu verwenden, wodurch die Paare so erstellt werden, wie Sie sie anfordern. zip() in Python 3 verhält sich jedoch standardmäßig so.

Für Ihren Fall

>>> import numpy as np 
>>> a = np.array([1,3,6,3,7,8,3,2,9,10,14,6]) 
>>> b = np.array([2,4,15,4,7,9,2,2,0,11,4,15]) 
>>> a, b = delete_duplicate_pairs(a, b) 
>>> a 
array([ 1, 3, 6, 7, 8, 3, 2, 9, 10, 14]) 
>>> b 
array([ 2, 4, 15, 7, 9, 2, 2, 0, 11, 4]) 

Nun es kommt alles darauf an, welche Werte Ihre Arrays halten. Wenn Sie nur die Werte 0-9 haben, gibt es nur 100 eindeutige Paare und die meisten Elemente werden Duplikate sein, was Ihnen Zeit spart. Bei 20 Millionen Elementen für a und b, die nur Werte zwischen 0 und 9 enthalten, ist der Prozess in 6 Sekunden abgeschlossen. Bei Werten zwischen 0 und 999 dauert es 12 Sekunden.

+0

Vielen Dank, ich werde es versuchen. Aber ich habe vergessen zu erwähnen, dass die beiden Arrays, die ich habe, eine Float-Nummer zwischen 0 - 50 enthalten. –

Verwandte Themen