Quiero descubrir cómo eliminar los valores nan de mi matriz. Mi matriz se parece a esto:
x = [1400, 1500, 1600, nan, nan, nan ,1700] #Not in this exact configuration
¿Cómo puedo eliminar los nan
valores de x
?
Quiero descubrir cómo eliminar los valores nan de mi matriz. Mi matriz se parece a esto:
x = [1400, 1500, 1600, nan, nan, nan ,1700] #Not in this exact configuration
¿Cómo puedo eliminar los nan
valores de x
?
Respuestas:
Si está usando numpy para sus matrices, también puede usar
x = x[numpy.logical_not(numpy.isnan(x))]
Equivalentemente
x = x[~numpy.isnan(x)]
[Gracias a chbrown por la taquigrafía añadida]
Explicación
La función interna, numpy.isnan
devuelve una matriz booleana / lógica que tiene el valor en True
todas partes que x
no es un número. Como queremos lo contrario, usamos el operador lógico-no, ~
para obtener una matriz con True
s en todas partes que x
sea un número válido.
Por último, usamos esta matriz lógica para indexar en la matriz original x
, para recuperar solo los valores que no son NaN.
x = x[numpy.isfinite(x)]
x = x[~numpy.isnan(x)]
, que es equivalente a la respuesta original de mutzmatron, pero más corto. En caso de que quiera mantener sus infinitos alrededor, sepa eso numpy.isfinite(numpy.inf) == False
, por supuesto, pero ~numpy.isnan(numpy.inf) == True
.
np.where(np.isfinite(x), x, 0)
x
no es una matriz numpy. Si desea utilizar la indexación lógica, debe ser una matriz, por ejemplox = np.array(x)
filter(lambda v: v==v, x)
funciona tanto para las listas como para la matriz numpy ya que v! = v solo para NaN
x
especificarse una vez en lugar de soluciones del tipo x[~numpy.isnan(x)]
. Esto es conveniente cuando x
se define mediante una expresión larga y no desea saturar el código creando una variable temporal para almacenar el resultado de esta expresión larga.
Prueba esto:
import math
print [value for value in x if not math.isnan(value)]
Para más información, lea en Lista de comprensiones .
print ([value for value in x if not math.isnan(value)])
np
paquete: Entonces devuelve su lista sin las nans:[value for value in x if not np.isnan(value)]
Para mí, la respuesta de @jmetz no funcionó, sin embargo, el uso de pandas isnull () sí.
x = x[~pd.isnull(x)]
Haciendo lo anterior:
x = x[~numpy.isnan(x)]
o
x = x[numpy.logical_not(numpy.isnan(x))]
Descubrí que restablecer la misma variable (x) no eliminaba los valores reales de nan y tenía que usar una variable diferente. Establecerlo en una variable diferente eliminó los nans. p.ej
y = x[~numpy.isnan(x)]
x
sobrescribir con el nuevo valor (es decir, sin los NaNs ...) . ¿Puede proporcionar más información sobre por qué esto podría estar sucediendo?
Como lo demuestran otros
x[~numpy.isnan(x)]
trabajos. Pero arrojará un error si el tipo de archivo numpy no es un tipo de datos nativo, por ejemplo, si es un objeto. En ese caso puedes usar pandas.
x[~pandas.isna(x)] or x[~pandas.isnull(x)]
La respuesta aceptada cambia de forma para las matrices 2d. Presento una solución aquí, usando la funcionalidad Pandas dropna () . Funciona para matrices 1D y 2D. En el caso 2D, puede elegir el clima para soltar la fila o columna que contiene 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='')
Resultado:
==================== 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.]
Una forma más simple es:
numpy.nan_to_num(x)
Documentación: https://docs.scipy.org/doc/numpy/reference/generated/numpy.nan_to_num.html
NaN
s con un gran número, mientras que el OP solicitó eliminar por completo los elementos.
Este es mi enfoque para filtrar ndarray "X" para NaNs e infs,
Creo un mapa de filas sin ninguno NaN
y ninguno de la inf
siguiente manera:
idx = np.where((np.isnan(X)==False) & (np.isinf(X)==False))
idx es una tupla. Su segunda columna ( idx[1]
) contiene los índices de la matriz, donde no se encuentra NaN ni inf en la fila.
Luego:
filtered_X = X[idx[1]]
filtered_X
contiene X sin NaN
ni inf
.
La respuesta de @ jmetz es probablemente la que más necesita la gente; sin embargo, produce una matriz unidimensional, por ejemplo, hace que sea inutilizable eliminar filas o columnas enteras en matrices.
Para hacerlo, uno debe reducir la matriz lógica a una dimensión, luego indexar la matriz de destino. Por ejemplo, lo siguiente eliminará las filas que tengan al menos un valor NaN:
x = x[~numpy.isnan(x).any(axis=1)]
Ver más detalles aquí .