2012-04-26 8 views
60

Qualcuno può consigliare un modo semplice per sostituire tutti i valori negativi in ​​un array con 0?numpy sostituisce i valori negativi nell'array

Sto avendo un blocco completo su come farlo utilizzando una matrice NumPy

esempio

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

ho bisogno di tornare

[1, 2, 3, 0, 5] 

a < 0 dà:

[False, False, False, True, False] 

Questo è dove mi sono bloccato - come utilizzare questo array di modificare la matrice originale

risposta

93

Sei a metà strada. Prova:

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

In [5]: a 
Out[5]: array([1, 2, 3, 0, 5]) 
68

Prova 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]) 

È possibile ritagliare solo la metà inferiore con clip(0).

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

È possibile ritagliare solo la metà superiore con clip(max=n). (Questo è molto meglio del mio precedente suggerimento, che ha coinvolto passando NaN al primo parametro e con out per costringere il tipo.):

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

Un altro approccio interessante è quello di utilizzare where:

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

Infine, considera la risposta di aix. Preferisco clip per operazioni semplici perché è auto-documentante, ma la sua risposta è preferibile per operazioni più complesse.

+1

a.clip (0) sarebbero sufficienti poiché l'OP vuole solo sostituire i valori negativi. a.clip (0, 10) escluderebbe qualsiasi valore superiore a 10. – Usagi

+1

@Hiett - Ho appena provato e la clip ne richiederà una. Il primo è assunto min. – Usagi

+0

deve essere un problema di versione con numpy - heres my ouptut: (Pdb) np.clip (w, 0) *** TypeError: clip() richiede almeno 3 argomenti (2 dati) - mentre: (Pdb) np.clip (w, 0,1e6) array ([[0., 0.605] ]) – bph

2

Ecco un modo per farlo in Python senza numpy. Creare una funzione che restituisca ciò che si desidera e utilizzare una comprensione di lista o la funzione map.

>>> 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] 
+1

era andato su questa rotta ma pensavo ci fosse un modo più semplice, più matlab less python per farlo con numpy (come stavo usando array piuttosto che liste comunque). la clip è perfetta – bph

8

Un'altra soluzione Python minimalista senza utilizzare NumPy:

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

Non c'è bisogno di definire tutte le funzioni aggiuntive.

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

rendimenti:

[1, 2, 3, 0, 0, 6] 
+0

che è bello - mi stavo chiedendo quale sarebbe stata la sintassi per mettere l'istruzione if all'interno della comprensione della lista - stavo andando male attaccandolo dopo il ciclo for e solo dopo aver ottenuto due valori indietro, ad es. [0, 0] per il tuo elenco di esempio – bph

+0

Ho fatto lo stesso quando ho appreso originariamente la comprensione delle liste e stavo provando cose diverse per testare la mia comprensione - mi sembrava più intuitivo metterlo dopo il ciclo for anche per me. Ora, però, questo fa :) Mettendolo prima che il 'for' lo applichi a ogni elemento della lista, mettendolo dopo, significa che solo se la condizione è soddisfatta entra nella lista risultante. – Levon

+0

@Usagi Grazie per aver segnalato la mia precedente errata lettura di questa domanda, ho corretto il codice. – Levon

3

E ancora un'altra possibilità:

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

In [3]: where(a<0, 0, a) 
Out[3]: array([1, 2, 3, 0, 5]) 
Problemi correlati