2012-07-23 17 views
98

Voglio capire come rimuovere i valori nan dal mio array. Assomiglia a questo:Rimozione di valori nan da un array

x = [1400, 1500, 1600, nan, nan, nan ,1700] #Not in this exact configuration 

Sono relativamente nuovo a Python quindi sto ancora imparando. Qualche consiglio?

risposta

178

Se stai usando NumPy per gli array, è anche possibile utilizzare

x = x[numpy.logical_not(numpy.isnan(x))] 

Equivalentemente

x = x[~numpy.isnan(x)] 

[Grazie a chbrown per la stenografia aggiunto]

Spiegazione

La funzione interna, numpy.isnan restituisce un array booleano/logico che ha il valore True ovunque che x non sia un numero. Come vogliamo il contrario, usiamo l'operatore logico-non, ~ per ottenere un array con True s ovunque che xsia un numero valido.

Infine, utilizziamo questo array logico per indicizzare nell'array originale x, per recuperare solo i valori non NaN.

+17

Oppure 'x = x [numpy.isfinite (x)]' – lazy1

+11

Oppure 'x = x [~ numpy.isnan (x)] ', che equivale alla risposta originale di mutzmatron , ma più breve. Nel caso in cui vuoi mantenere i tuoi infiniti in giro, sappi che 'numpy.isfinite (numpy.inf) == False', ovviamente, ma' ~ numpy.isnan (numpy.inf) == True'. – chbrown

+0

@ dax-felizv Sono d'accordo con @chbrown, NaN e Infinite non sono gli stessi in 'numpy'. @chbrown: grazie per aver evidenziato la stenografia di 'logical_not', ma attenzione che è molto più lento - http://stackoverflow.com/questions/15998188/how-can-i-obtain-the-element-wise-logical- non-of-a-pandas-series, http://stackoverflow.com/questions/13600988/python-tilde-unary-operator-as-negation-numpy-bool-array – jmetz

32

Prova questo:

import math 
print [value for value in x if not math.isnan(value)] 

Per di più, continuate a leggere List Comprehensions.

+1

Se stai usando NumPy sia la mia risposta e che da @ lazy1 sono quasi un ordine di grandezza più veloce rispetto alla lista di comprensione - La soluzione di lazy1 è leggermente più veloce (anche se tecnicamente non restituirà alcun valore di infinito). – jmetz

+0

Non dimenticare le parentesi :) 'print ([valore per valore in x se non math.isnan (valore)])' – hypers

24
filter(lambda v: v==v, x) 

opere sia per liste e array di NumPy dal v = v solo per NaN

+2

Un hack ma particolarmente utile nel caso in cui si filtrano nans da una matrice di oggetti con tipi misti, come stringhe e nans. –

+0

Soluzione molto pulita. – Moondra

3

fare quanto sopra:

x = x[~numpy.isnan(x)] 

o

x = x[numpy.logical_not(numpy.isnan(x))] 

ho scoperto che il ripristino alla stessa variabile (x) non sono stati rimossi i reali valori nan e si è dovuto utilizzare una variabile diversa. Impostandolo su una variabile diversa è stato rimosso il nans. ad es.

y = x[~numpy.isnan(x)] 
+0

Questo è strano; secondo [i documenti] (https://docs.scipy.org/doc/numpy/reference/arrays.indexing.html#advanced-indexing), l'indicizzazione di array booleani (che questo è), è in ** indicizzazione avanzata * * che apparentemente "restituisce sempre una copia dei dati", quindi dovresti sovrascrivere 'x' con il nuovo valore (cioè senza i NaNs ...). Puoi fornire ulteriori informazioni sul perché questo potrebbe accadere? – jmetz

4

Per me la risposta di @jmetz non ha funzionato, tuttavia utilizzando pandas isnull() ha fatto.

x = x[~pd.isnull(x)] 
1

come mostrato da altri

x[~numpy.isnan(x)] 

opere. Ma genererà un errore se il dtype numpy non è un tipo di dati nativo, ad esempio se è un oggetto. In tal caso puoi usare i panda.

x[~pandas.isnan(x)] 
0

Se stai usando numpy

# first get the indices where the values are finite 
ii = np.isfinite(x) 

# second get the values 
x = x[ii] 
Problemi correlati