Voglio capire come rimuovere i valori nan dal mio array. Il mio array è simile al seguente:
x = [1400, 1500, 1600, nan, nan, nan ,1700] #Not in this exact configuration
Come posso rimuovere i nan
valori da x
?
Voglio capire come rimuovere i valori nan dal mio array. Il mio array è simile al seguente:
x = [1400, 1500, 1600, nan, nan, nan ,1700] #Not in this exact configuration
Come posso rimuovere i nan
valori da x
?
Risposte:
Se stai usando numpy per le tue matrici, puoi anche usare
x = x[numpy.logical_not(numpy.isnan(x))]
Equivalentemente
x = x[~numpy.isnan(x)]
[Grazie a chbrown per la scorciatoia aggiunta]
Spiegazione
La funzione interna, numpy.isnan
restituisce un array booleano / logico che ha True
ovunque un valore x
diverso da un numero. Come vogliamo il contrario, usiamo l'operatore non logico, ~
per ottenere un array con True
s ovunque che x
sia un numero valido.
Infine usiamo questo array logico per indicizzare l'array originale x
, per recuperare solo i valori non NaN.
x = x[numpy.isfinite(x)]
x = x[~numpy.isnan(x)]
, che equivale alla risposta originale di mutzmatron, ma più breve. Nel caso in cui desideri mantenere i tuoi infiniti, sappi che numpy.isfinite(numpy.inf) == False
, ovviamente, ma ~numpy.isnan(numpy.inf) == True
.
np.where(np.isfinite(x), x, 0)
x
non è un array intorpidito. Se si desidera utilizzare l'indicizzazione logica, deve essere un array - ad esempiox = np.array(x)
filter(lambda v: v==v, x)
funziona sia per elenchi che per numpy array poiché v! = v solo per NaN
x
essere specificato solo una volta rispetto alle soluzioni del tipo x[~numpy.isnan(x)]
. Ciò è utile quando x
è definito da un'espressione lunga e non si desidera ingombrare il codice creando una variabile temporanea per memorizzare il risultato di questa espressione lunga.
Prova questo:
import math
print [value for value in x if not math.isnan(value)]
Per ulteriori informazioni, leggi l' elenco Comprensioni .
print ([value for value in x if not math.isnan(value)])
np
pacchetto: Quindi restituisce la tua lista senza i nans:[value for value in x if not np.isnan(value)]
Per me la risposta di @jmetz non ha funzionato, tuttavia usando panda isnull () ha funzionato.
x = x[~pd.isnull(x)]
Fare quanto sopra:
x = x[~numpy.isnan(x)]
o
x = x[numpy.logical_not(numpy.isnan(x))]
Ho scoperto che il ripristino sulla stessa variabile (x) non ha rimosso i valori nan effettivi e ha dovuto utilizzare una variabile diversa. Impostandolo su una variabile diversa rimosso i nans. per esempio
y = x[~numpy.isnan(x)]
x
sovrascrivere con il nuovo valore (cioè senza i NaNs ...) . Potete fornire ulteriori informazioni sul perché ciò potrebbe accadere?
Come mostrato da altri
x[~numpy.isnan(x)]
lavori. Ma genererà un errore se il tipo numpy non è un tipo di dati nativo, ad esempio se è un oggetto. In quel caso puoi usare i panda.
x[~pandas.isna(x)] or x[~pandas.isnull(x)]
La risposta accettata cambia forma per array 2d. Vi presento una soluzione qui, usando la funzionalità di Pandas dropna () . Funziona con array 1D e 2D. Nel caso 2D puoi scegliere il tempo in cui rilasciare la riga o la colonna contenente np.nan
.
import pandas as pd
import numpy as np
def dropna(arr, *args, **kwarg):
assert isinstance(arr, np.ndarray)
dropped=pd.DataFrame(arr).dropna(*args, **kwarg).values
if arr.ndim==1:
dropped=dropped.flatten()
return dropped
x = np.array([1400, 1500, 1600, np.nan, np.nan, np.nan ,1700])
y = np.array([[1400, 1500, 1600], [np.nan, 0, np.nan] ,[1700,1800,np.nan]] )
print('='*20+' 1D Case: ' +'='*20+'\nInput:\n',x,sep='')
print('\ndropna:\n',dropna(x),sep='')
print('\n\n'+'='*20+' 2D Case: ' +'='*20+'\nInput:\n',y,sep='')
print('\ndropna (rows):\n',dropna(y),sep='')
print('\ndropna (columns):\n',dropna(y,axis=1),sep='')
print('\n\n'+'='*20+' x[np.logical_not(np.isnan(x))] for 2D: ' +'='*20+'\nInput:\n',y,sep='')
print('\ndropna:\n',x[np.logical_not(np.isnan(x))],sep='')
Risultato:
==================== 1D Case: ====================
Input:
[1400. 1500. 1600. nan nan nan 1700.]
dropna:
[1400. 1500. 1600. 1700.]
==================== 2D Case: ====================
Input:
[[1400. 1500. 1600.]
[ nan 0. nan]
[1700. 1800. nan]]
dropna (rows):
[[1400. 1500. 1600.]]
dropna (columns):
[[1500.]
[ 0.]
[1800.]]
==================== x[np.logical_not(np.isnan(x))] for 2D: ====================
Input:
[[1400. 1500. 1600.]
[ nan 0. nan]
[1700. 1800. nan]]
dropna:
[1400. 1500. 1600. 1700.]
Un modo più semplice è:
numpy.nan_to_num(x)
Documentazione: https://docs.scipy.org/doc/numpy/reference/generated/numpy.nan_to_num.html
NaN
s con un numero elevato, mentre l'OP ha chiesto di rimuovere completamente gli elementi.
Questo è il mio approccio per filtrare ndarray "X" per NaNs e infs,
Creo una mappa di righe senza nessuna NaN
e nessuna inf
come segue:
idx = np.where((np.isnan(X)==False) & (np.isinf(X)==False))
idx è una tupla. La sua seconda colonna ( idx[1]
) contiene gli indici dell'array, dove nessun NaN né inf sono stati trovati lungo la riga.
Poi:
filtered_X = X[idx[1]]
filtered_X
contiene X senza NaN
nor inf
.
La risposta di @jmetz è probabilmente quella di cui molte persone hanno bisogno; tuttavia produce una matrice unidimensionale, ad esempio rendendo inutilizzabile la rimozione di intere righe o colonne nelle matrici.
Per fare ciò, si dovrebbe ridurre l'array logico a una dimensione, quindi indicizzare l'array di destinazione. Ad esempio, quanto segue rimuoverà le righe che hanno almeno un valore NaN:
x = x[~numpy.isnan(x).any(axis=1)]
Vedi maggiori dettagli qui .