numpy ersetzt negative Werte im Array

88

Kann jemand eine einfache Möglichkeit empfehlen, alle negativen Werte in einem Array durch 0 zu ersetzen?

Ich habe einen vollständigen Block, wie man es mit einem Numpy-Array macht

z.B

a = array([1, 2, 3, -4, 5])

Ich muss zurückkehren

[1, 2, 3, 0, 5]

a < 0 gibt:

[False, False, False, True, False]

Hier stecke ich fest - wie man dieses Array verwendet, um das ursprüngliche Array zu ändern

bph
quelle

Antworten:

135

Du bist auf halbem Weg da. Versuchen:

In [4]: a[a < 0] = 0

In [5]: a
Out[5]: array([1, 2, 3, 0, 5])
NPE
quelle
89

Versuchen Sie numpy.clip:

>>> import numpy
>>> a = numpy.arange(-10, 10)
>>> a
array([-10,  -9,  -8,  -7,  -6,  -5,  -4,  -3,  -2,  -1,   0,   1,   2,
         3,   4,   5,   6,   7,   8,   9])
>>> a.clip(0, 10)
array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9])

Sie können nur die untere Hälfte mit abschneiden clip(0).

>>> a = numpy.array([1, 2, 3, -4, 5])
>>> a.clip(0)
array([1, 2, 3, 0, 5])

Sie können nur die obere Hälfte mit abschneiden clip(max=n). (Dies ist viel besser als mein vorheriger Vorschlag, bei dem NaNzum ersten Parameter outübergegangen und der Typ erzwungen wurde.):

>>> a.clip(max=2)
array([ 1,  2,  2, -4,  2])

Ein weiterer interessanter Ansatz ist where:

>>> numpy.where(a <= 2, a, 2)
array([ 1,  2,  2, -4,  2])

Betrachten Sie abschließend die Antwort von aix . Ich bevorzuge clipeinfache Operationen, weil sie sich selbst dokumentieren, aber seine Antwort ist für komplexere Operationen vorzuziehen.

senderle
quelle
1
a.clip (0) würde ausreichen, da das OP nur negative Werte ersetzen möchte. a.clip (0, 10) würde alles über 10 ausschließen.
Usagi
1
@Hiett - Ich habe es gerade versucht und der Clip wird einen nehmen. Zunächst wird min angenommen.
Usagi
muss ein Versionsproblem mit numpy sein - hier ist mein ouptut: (Pdb) np.clip (w, 0) *** TypeError: clip () akzeptiert mindestens 3 Argumente (2 angegeben) - während: (Pdb) np.clip ( w, 0,1e6) Array ([[0., 0.605]])
bph
1
@Hiett, von welcher Version numpy? Haben Sie die Clip- Methode von ausprobiert a? Die eingebaute Funktion numpy.clipgibt mir den gleichen Fehler, die Methode jedoch nicht.
senderle
yeh wenn du es so nennst, scheint es zu funktionieren, zB p w.clip (0) array ([[0., 0.605]]) - wie queer?
bph
10

Eine weitere minimalistische Python-Lösung ohne Verwendung von numpy:

[0 if i < 0 else i for i in a]

Es müssen keine zusätzlichen Funktionen definiert werden.

a = [1, 2, 3, -4, -5.23, 6]
[0 if i < 0 else i for i in a]

Ausbeuten:

[1, 2, 3, 0, 0, 6]
Levon
quelle
1
Das ist schön - ich habe mich gefragt, wie die Syntax lauten soll, um die if-Anweisung in das Listenverständnis aufzunehmen. Ich habe einen Fehler gemacht, indem ich sie nach der for-Schleife eingefügt und erst dann zwei Werte zurückbekommen habe, z. B. [0, 0] für Ihr Beispiel Liste
bph
Ich habe das Gleiche getan, als ich ursprünglich etwas über das Listenverständnis gelernt hatte und verschiedene Dinge ausprobiert habe, um mein Verständnis zu testen - es schien intuitiver, es auch für mich nach der for-Schleife zu setzen. Dies ist jedoch der Fall :) Wenn Sie es vor das forAnwenden auf jedes Element der Liste setzen und danach setzen, bedeutet dies nur, dass es in die resultierende Liste aufgenommen wird, wenn die Bedingung erfüllt ist.
Levon
2
@Hiett Es wird nur der ternäre Operator ( i < 0 ? 0 : iin C) innerhalb eines Listenverständnisses verwendet. Setzen Sie Klammern ein, um es klarer zu machen [(0 if i < 0 else i) for i in a]. Durch Setzen des if after wird der Filterteil des Listenausdruckskonstrukts verwendet. [(i) for i in a if i < 0]gibt nur eine Liste von Elementen zurück, die kleiner als Null sind.
Paul S
2
Numpy ist leistungsstark, da es einen Großteil der Berechnungen mit kompiliertem C-Code durchführt und somit schneller ist. Wenn ich diese Methode mit den anderen vergleiche, finde ich fast einen 10-fachen Geschwindigkeitsfaktorunterschied (dies ist langsamer). Dies ist zwar intuitiv und leicht zu lesen, aber definitiv nicht für Rechenintensive geeignet.
rspencer
4

Und noch eine Möglichkeit:

In [2]: a = array([1, 2, 3, -4, 5])

In [3]: where(a<0, 0, a)
Out[3]: array([1, 2, 3, 0, 5])
Ramon Crehuet
quelle
2

Hier ist eine Möglichkeit, dies in Python ohne Numpy zu tun. Erstellen Sie eine Funktion, die das zurückgibt, was Sie möchten, und verwenden Sie ein Listenverständnis oder die Kartenfunktion .

>>> a = [1, 2, 3, -4, 5]

>>> def zero_if_negative(x):
...   if x < 0:
...     return 0
...   return x
...

>>> [zero_if_negative(x) for x in a]
[1, 2, 3, 0, 5]

>>> map(zero_if_negative, a)
[1, 2, 3, 0, 5]
Kekoa
quelle
1
Ich war diesen Weg gegangen, dachte aber, dass es einen einfacheren, matlab weniger Python-Weg geben muss, um es mit numpy zu tun (da ich sowieso eher Arrays als Listen verwendete). Clip ist perfekt
bph