Ich habe ein sehr großes NumPy-Array
1 40 3
4 50 4
5 60 7
5 49 6
6 70 8
8 80 9
8 72 1
9 90 7
....
Ich möchte überprüfen, ob in der ersten Spalte des Arrays ein Wert vorhanden ist. Ich habe eine Reihe von hausgemachten Methoden (z. B. Durchlaufen jeder Zeile und Überprüfen), aber angesichts der Größe des Arrays möchte ich die effizienteste Methode finden.
Vielen Dank!
python
performance
numpy
thegreatt
quelle
quelle
Antworten:
Wie wäre es mit
if value in my_array[:, col_num]: do_whatever
Bearbeiten: Ich denke,
__contains__
ist so implementiert, dass dies die gleiche wie @ detlys Version istquelle
numpy
‚s -any()
Funktion so stark vor kurzem habe ich über das gute alte völlig vergessenin
.value in …
kann dies schneller sein alsany(… == value)
, da es über die Array-Elemente iterieren und anhalten kann, wenn der Wert angetroffen wird (anstatt zu berechnen, ob jedes Array-Element dem Wert entspricht, und dann zu überprüfen, ob eines der booleschen Ergebnisse wahr ist). .any
Kurzschluss, nicht wahrnumpy
?Das offensichtlichste für mich wäre:
np.any(my_array[:, 0] == value)
quelle
my_array[:, 0]
gibt Ihnen alle Zeilen (angezeigt durch:
) und für jede Zeile das0
th-Element, dh die erste Spalte. Dies ist beispielsweise ein einfaches eindimensionales Array[1, 3, 6, 2, 9]
. Wenn Sie den==
Operator in numpy mit einem Skalar verwenden, führt er einen elementweisen Vergleich durch und gibt ein boolesches numpy-Array mit derselben Form wie das Array zurück. Also[1, 3, 6, 2, 9] == 3
gibt[False, True, False, False, False]
. Schließlichnp.any
prüft, ob alle Werte in diesem Array sindTrue
.Um mehrere Werte zu überprüfen, können Sie numpy.in1d () verwenden, eine elementweise Funktionsversion des Python-Schlüsselworts in. Wenn Ihre Daten sortiert sind, können Sie numpy.searchsorted () verwenden:
import numpy as np data = np.array([1,4,5,5,6,8,8,9]) values = [2,3,4,6,7] print np.in1d(values, data) index = np.searchsorted(data, values) print data[index] == values
quelle
numpy.in1d()
und für die sehr schnellensearchsorted()
.IndexError
Element auslöst, dasvalues
größer als der größte Wert von istdata
, sodass besondere Aufmerksamkeit erforderlich ist.index
mitindex % len(data)
odernp.append(index[:-1],0)
äquivalent in diesem Fall.Faszinierend. Ich musste die Geschwindigkeit einer Reihe von Schleifen verbessern, die auf dieselbe Weise eine Matching-Index-Bestimmung durchführen müssen. Also habe ich beschlossen, alle Lösungen hier zusammen mit einigen Riffs zu planen.
Hier sind meine Geschwindigkeitstests für Python 2.7.10:
import timeit timeit.timeit('N.any(N.in1d(sids, val))', setup = 'import numpy as N; val = 20010401020091; sids = N.array([20010401010101+x for x in range(1000)])')
18.86137104034424
timeit.timeit('val in sids', setup = 'import numpy as N; val = 20010401020091; sids = [20010401010101+x for x in range(1000)]')
15.061666011810303
timeit.timeit('N.in1d(sids, val)', setup = 'import numpy as N; val = 20010401020091; sids = N.array([20010401010101+x for x in range(1000)])')
11.613027095794678
timeit.timeit('N.any(val == sids)', setup = 'import numpy as N; val = 20010401020091; sids = N.array([20010401010101+x for x in range(1000)])')
7.670552015304565
timeit.timeit('val in sids', setup = 'import numpy as N; val = 20010401020091; sids = N.array([20010401010101+x for x in range(1000)])')
5.610057830810547
timeit.timeit('val == sids', setup = 'import numpy as N; val = 20010401020091; sids = N.array([20010401010101+x for x in range(1000)])')
1.6632978916168213
timeit.timeit('val in sids', setup = 'import numpy as N; val = 20010401020091; sids = set([20010401010101+x for x in range(1000)])')
0,0548710823059082
timeit.timeit('val in sids', setup = 'import numpy as N; val = 20010401020091; sids = dict(zip([20010401010101+x for x in range(1000)],[True,]*1000))')
0,054754018783569336
Sehr überraschend! Größenordnungsunterschiede!
Zusammenfassend lässt sich sagen, ob Sie nur wissen möchten, ob sich etwas in einer 1D-Liste befindet oder nicht:
Wenn Sie auch wissen möchten, wo sich etwas in der Liste befindet (Reihenfolge ist wichtig):
quelle
Das Hinzufügen zu @ HYRYs Antwort in1d scheint für numpy am schnellsten zu sein. Dies verwendet Numpy 1.8 und Python 2.7.6.
In diesem Test war in1d am schnellsten:
a = arange(0,99999,3) %timeit 10 in a %timeit in1d(a, 10) 10000 loops, best of 3: 150 µs per loop 10000 loops, best of 3: 61.9 µs per loop
Die Verwendung eines Python-Sets scheint am schnellsten zu sein:
s = set(range(0, 99999, 3)) %timeit 10 in s 10000000 loops, best of 3: 47 ns per loop
quelle
set
. OP beginnt mit einem NumPy-Array.Der meiner Meinung nach bequemste Weg ist:
(Val in X[:, col_num])
Dabei ist Val der Wert, nach dem Sie suchen möchten, und X das Array. Angenommen, Sie möchten in Ihrem Beispiel überprüfen, ob der Wert 8 in Ihrer dritten Spalte vorhanden ist. Einfach schreiben
(8 in X[:, 2])
Dies gibt True zurück, wenn 8 in der dritten Spalte steht, andernfalls False.
quelle