Je veux savoir comment supprimer les valeurs nan de mon tableau. Mon tableau ressemble à ceci:
x = [1400, 1500, 1600, nan, nan, nan ,1700] #Not in this exact configuration
Comment puis-je supprimer les nan
valeurs de x
?
Je veux savoir comment supprimer les valeurs nan de mon tableau. Mon tableau ressemble à ceci:
x = [1400, 1500, 1600, nan, nan, nan ,1700] #Not in this exact configuration
Comment puis-je supprimer les nan
valeurs de x
?
Réponses:
Si vous utilisez numpy pour vos tableaux, vous pouvez également utiliser
x = x[numpy.logical_not(numpy.isnan(x))]
De manière équivalente
x = x[~numpy.isnan(x)]
[Merci à chbrown pour le raccourci ajouté]
Explication
La fonction interne, numpy.isnan
renvoie un tableau booléen / logique qui a True
partout la valeur qui x
n'est pas un nombre. Comme nous voulons le contraire, nous utilisons l'opérateur non logique ~
pour obtenir un tableau avec True
s partout qui x
est un nombre valide.
Enfin, nous utilisons ce tableau logique pour indexer dans le tableau d'origine x
, pour récupérer uniquement les valeurs non NaN.
x = x[numpy.isfinite(x)]
x = x[~numpy.isnan(x)]
, ce qui équivaut à la réponse originale de mutzmatron, mais plus court. Dans le cas où vous souhaitez garder vos infinis, sachez que numpy.isfinite(numpy.inf) == False
, bien sûr, mais ~numpy.isnan(numpy.inf) == True
.
np.where(np.isfinite(x), x, 0)
x
n'est pas un tableau numpy. Si vous souhaitez utiliser l'indexation logique, ce doit être un tableau - par exemplex = np.array(x)
filter(lambda v: v==v, x)
fonctionne à la fois pour les listes et le tableau numpy puisque v! = v uniquement pour NaN
x
être spécifié qu'une seule fois, contrairement aux solutions du type x[~numpy.isnan(x)]
. C'est pratique quand x
est défini par une expression longue et que vous ne voulez pas encombrer le code en créant une variable temporaire pour stocker le résultat de cette expression longue.
Essaye ça:
import math
print [value for value in x if not math.isnan(value)]
Pour en savoir plus, lisez la liste des compréhensions .
print ([value for value in x if not math.isnan(value)])
np
package: renvoie donc votre liste sans les nans:[value for value in x if not np.isnan(value)]
Pour moi, la réponse de @jmetz n'a pas fonctionné, mais l'utilisation de pandas isnull () l'a fait.
x = x[~pd.isnull(x)]
Faire ce qui précède:
x = x[~numpy.isnan(x)]
ou
x = x[numpy.logical_not(numpy.isnan(x))]
J'ai trouvé que la réinitialisation à la même variable (x) ne supprimait pas les valeurs nanos réelles et devait utiliser une variable différente. Le définir sur une variable différente a supprimé les nans. par exemple
y = x[~numpy.isnan(x)]
x
écraser avec la nouvelle valeur (c'est-à-dire sans les NaN ...) . Pouvez-vous fournir plus d'informations sur la raison pour laquelle cela pourrait se produire?
Comme le montrent d'autres
x[~numpy.isnan(x)]
travaux. Mais cela générera une erreur si le type numpy n'est pas un type de données natif, par exemple s'il s'agit d'un objet. Dans ce cas, vous pouvez utiliser des pandas.
x[~pandas.isna(x)] or x[~pandas.isnull(x)]
La réponse acceptée change de forme pour les tableaux 2D. Je présente ici une solution, en utilisant la fonctionnalité Pandas dropna () . Il fonctionne pour les tableaux 1D et 2D. Dans le cas 2D, vous pouvez choisir la météo pour supprimer la ligne ou la colonne contenant 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='')
Résultat:
==================== 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 moyen le plus simple est:
numpy.nan_to_num(x)
Documentation: https://docs.scipy.org/doc/numpy/reference/generated/numpy.nan_to_num.html
NaN
s par un grand nombre, tandis que l'OP a demandé de supprimer entièrement les éléments.
Ceci est mon approche pour filtrer ndarray "X" pour NaNs et infs,
Je crée une carte de lignes sans aucun NaN
et inf
comme suit:
idx = np.where((np.isnan(X)==False) & (np.isinf(X)==False))
idx est un tuple. C'est la deuxième colonne ( idx[1]
) contient les indices du tableau, où aucun NaN ni inf ne se trouvent à travers la ligne.
Ensuite:
filtered_X = X[idx[1]]
filtered_X
contient X sans NaN
ni inf
.
La réponse de @ jmetz est probablement celle dont la plupart des gens ont besoin; cependant, il donne un tableau unidimensionnel, ce qui rend par exemple inutilisable la suppression de lignes ou de colonnes entières dans les matrices.
Pour ce faire, il faut réduire le tableau logique à une dimension, puis indexer le tableau cible. Par exemple, ce qui suit supprimera les lignes qui ont au moins une valeur NaN:
x = x[~numpy.isnan(x).any(axis=1)]
Voir plus de détails ici .