web-dev-qa-db-fra.com

Comment vérifier si une valeur est NaN dans un Pandas DataFrame

Dans les pandas Python, quel est le meilleur moyen de vérifier si un DataFrame a une (ou plusieurs) valeur NaN?

Je connais la fonction pd.isnan, mais cela retourne un DataFrame de booléens pour chaque élément. Ce post ici ne répond pas exactement à ma question non plus.

323
hlin117

La réponse de jwilner est parfaite. J'explorais pour voir s'il y avait une option plus rapide, car d'après mon expérience, sommer des tableaux plats est (étrangement) plus rapide que de compter. Ce code semble plus rapide:

df.isnull().values.any()

Par exemple:

In [2]: df = pd.DataFrame(np.random.randn(1000,1000))

In [3]: df[df > 0.9] = pd.np.nan

In [4]: %timeit df.isnull().any().any()
100 loops, best of 3: 14.7 ms per loop

In [5]: %timeit df.isnull().values.sum()
100 loops, best of 3: 2.15 ms per loop

In [6]: %timeit df.isnull().sum().sum()
100 loops, best of 3: 18 ms per loop

In [7]: %timeit df.isnull().values.any()
1000 loops, best of 3: 948 µs per loop

df.isnull().sum().sum() est un peu plus lent, mais a bien sûr des informations supplémentaires - le nombre de NaNs.

405
S Anand

Vous avez plusieurs options. 

import pandas as pd
import numpy as np

df = pd.DataFrame(np.random.randn(10,6))
# Make a few areas have NaN values
df.iloc[1:3,1] = np.nan
df.iloc[5,3] = np.nan
df.iloc[7:9,5] = np.nan

Maintenant, le cadre de données ressemble à ceci:

          0         1         2         3         4         5
0  0.520113  0.884000  1.260966 -0.236597  0.312972 -0.196281
1 -0.837552       NaN  0.143017  0.862355  0.346550  0.842952
2 -0.452595       NaN -0.420790  0.456215  1.203459  0.527425
3  0.317503 -0.917042  1.780938 -1.584102  0.432745  0.389797
4 -0.722852  1.704820 -0.113821 -1.466458  0.083002  0.011722
5 -0.622851 -0.251935 -1.498837       NaN  1.098323  0.273814
6  0.329585  0.075312 -0.690209 -3.807924  0.489317 -0.841368
7 -1.123433 -1.187496  1.868894 -2.046456 -0.949718       NaN
8  1.133880 -0.110447  0.050385 -1.158387  0.188222       NaN
9 -0.513741  1.196259  0.704537  0.982395 -0.585040 -1.693810
  • Option 1 : df.isnull().any().any() - Ceci retourne une valeur booléenne

Vous connaissez le isnull() qui renverrait un cadre de données comme celui-ci:

       0      1      2      3      4      5
0  False  False  False  False  False  False
1  False   True  False  False  False  False
2  False   True  False  False  False  False
3  False  False  False  False  False  False
4  False  False  False  False  False  False
5  False  False  False   True  False  False
6  False  False  False  False  False  False
7  False  False  False  False  False   True
8  False  False  False  False  False   True
9  False  False  False  False  False  False

Si vous le définissez df.isnull().any(), vous pouvez trouver uniquement les colonnes qui ont des valeurs NaN:

0    False
1     True
2    False
3     True
4    False
5     True
dtype: bool

.any() vous indiquera si l’un des éléments ci-dessus est True

> df.isnull().any().any()
True
  • Option 2 : df.isnull().sum().sum() - Cette fonction renvoie un entier du nombre total de valeurs NaN:

Ceci fonctionne de la même manière que le .any().any(), en donnant d'abord une somme du nombre de valeurs NaN dans une colonne, puis la somme de ces valeurs:

df.isnull().sum()
0    0
1    2
2    0
3    1
4    0
5    2
dtype: int64

Enfin, pour obtenir le nombre total de valeurs NaN dans le DataFrame:

df.isnull().sum().sum()
5
126
Andy

Pour savoir quelles lignes contiennent des NaN dans une colonne spécifique:

nan_rows = df[df['name column'].isnull()]
40
Ihor Ivasiuk

Si vous avez besoin de savoir combien de lignes il y a avec "un ou plusieurs NaNs":

df.isnull().T.any().T.sum()

Ou si vous devez extraire ces lignes et les examiner:

nan_rows = df[df.isnull().T.any().T]
33
hobs

df.isnull().any().any() devrait le faire.

27
jwilner

Ajoutant à la réponse brillante de Hobs, je suis très novice en Python et en Pandas, alors veuillez indiquer si je me trompe.

Pour savoir quelles lignes ont des NaN:

nan_rows = df[df.isnull().any(1)]

effectuerait la même opération sans avoir besoin de transposer en spécifiant l’axe de any () comme 1 pour vérifier si «True» est présent dans les lignes. 

14
Ankit

Comme aucun n'a mentionné, il n'y a qu'une autre variable appelée hasnans

df[i].hasnans affichera True si une ou plusieurs des valeurs de la série pandas est NaN, False sinon. Notez que ce n'est pas une fonction.

version pandas '0.19.2' et '0.20.2'

10
yazhi

Puisque pandas doit le découvrir pour DataFrame.dropna(), j'ai jeté un coup d'œil à la façon dont ils l'ont implémenté et découvert qu'ils utilisaient DataFrame.count(), qui compte toutes les valeurs non nulles dans DataFrame. Cf. code source des pandas . Je n’ai pas évalué cette technique, mais j’imagine que les auteurs de la bibliothèque ont probablement fait le bon choix.

7
Marshall Farrier

Il suffit d'utiliser math.isnan (x) , Renvoie True si x est un NaN (pas un nombre) et False sinon.

4
江南消夏

À partir de la v0.23.2 , vous pouvez utiliser DataFrame.isna + DataFrame.any(axis=None)axis=None indique une réduction logique sur l'ensemble du DataFrame.

# Setup
df = pd.DataFrame({'A': [1, 2, np.nan], 'B' : [np.nan, 4, 5]})
df
     A    B
0  1.0  NaN
1  2.0  4.0
2  NaN  5.0

df.isna()

       A      B
0  False   True
1  False  False
2   True  False

df.isna().any(axis=None)
# True

Une autre option performante que vous pouvez utiliser est numpy.isnan :

np.isnan(df.values)

array([[False,  True],
       [False, False],
       [ True, False]])

np.isnan(df.values).any()
# True

Sinon, vérifiez la somme:

np.isnan(df.values).sum()
# 2

np.isnan(df.values).sum() > 0
# True

Vous pouvez également appeler de manière itérative Series.hasnans . Par exemple, pour vérifier si une seule colonne a des NaN, 

df['A'].hasnans
# True

Et pour vérifier si la colonne any contient des NaN, vous pouvez utiliser la compréhension avec any (opération consistant à court-circuiter).

any(df[c].hasnans for c in df)
# True

C'est en fait très rapide.

2
coldspeed

Voici un autre moyen intéressant de trouver null et de le remplacer par une valeur calculée

    #Creating the DataFrame

    testdf = pd.DataFrame({'Tenure':[1,2,3,4,5],'Monthly':[10,20,30,40,50],'Yearly':[10,40,np.nan,np.nan,250]})
    >>> testdf2
       Monthly  Tenure  Yearly
    0       10       1    10.0
    1       20       2    40.0
    2       30       3     NaN
    3       40       4     NaN
    4       50       5   250.0

    #Identifying the rows with empty columns
    nan_rows = testdf2[testdf2['Yearly'].isnull()]
    >>> nan_rows
       Monthly  Tenure  Yearly
    2       30       3     NaN
    3       40       4     NaN

    #Getting the rows# into a list
    >>> index = list(nan_rows.index)
    >>> index
    [2, 3]

    # Replacing null values with calculated value
    >>> for i in index:
        testdf2['Yearly'][i] = testdf2['Monthly'][i] * testdf2['Tenure'][i]
    >>> testdf2
       Monthly  Tenure  Yearly
    0       10       1    10.0
    1       20       2    40.0
    2       30       3    90.0
    3       40       4   160.0
    4       50       5   250.0
2
Jagannath Banerjee

Ou vous pouvez utiliser .info() sur la DF tel que:

df.info(null_counts=True) qui retourne le nombre de lignes non nuls dans une colonne telle que:

<class 'pandas.core.frame.DataFrame'>
Int64Index: 3276314 entries, 0 to 3276313
Data columns (total 10 columns):
n_matches                          3276314 non-null int64
avg_pic_distance                   3276314 non-null float64
1
Jan Sila

soit df le nom du Pandas DataFrame et toute valeur qui est numpy.nan est une valeur nulle.

  1. Si vous voulez voir quelles colonnes ont des valeurs nulles et lesquelles ne le sont pas (juste True et False)
    df.isnull().any()
  2. Si vous voulez voir uniquement les colonnes ayant des valeurs NULL
    df.loc[:, df.isnull().any()].columns
  3. Si vous voulez voir le nombre de NULL dans vos colonnes
    df.loc[:, list(df.loc[:, df.isnull().any()].columns)].isnull().sum()
  4. Si vous voulez voir le pourcentage de NULL dans vos colonnes
    df.loc[:,list(df.loc[:,df.isnull().any()].columns)].isnull().sum()/(len(df))*100

EDIT 1: Si vous voulez voir où vos données manquent visuellement:
import missingno
missingdata_df = df.columns[df.isnull().any()].tolist()
missingno.matrix(df[missingdata_df])

1
Naveen Kumar

J'utilise ce qui suit et le transforme en chaîne et recherche la valeur nan

   (str(df.at[index, 'column']) == 'nan')

Cela me permet de vérifier une valeur spécifique dans une série et pas seulement de revenir si elle est contenue quelque part dans la série.

1
Peter Thomas

Le mieux serait d'utiliser:

df.isna().any().any()

Voici pourquoi . Donc, isna() est utilisé pour définir isnull(), mais les deux sont identiques, bien sûr.

Ceci est encore plus rapide que la réponse acceptée et couvre tous les tableaux de panda 2D.

0
prosti
import missingno as msno
msno.matrix(df)  # just to visualize. no missing value.

enter image description here

0

df.isnull (). sum () Ceci vous donnera le nombre de toutes les valeurs NaN dans le DataFrame

0
Adarsh singh
df.apply(axis=0, func=lambda x : any(pd.isnull(x)))

Va vérifier pour chaque colonne si elle contient Nan ou non.

0
Alex Dlikman

Selon le type de données que vous utilisez, vous pouvez également obtenir le nombre de valeurs de chaque colonne lors de l'exécution de votre EDA en définissant dropna sur False. 

for col in df:
   print df[col].value_counts(dropna=False)

Fonctionne bien pour les variables catégorielles, moins quand vous avez plusieurs valeurs uniques.

0
andrewwowens