Comment compter les valeurs NaN dans une colonne dans pandas DataFrame

464

J'ai des données, dans lesquelles je veux trouver le nombre de NaN, de sorte que si elle est inférieure à un certain seuil, je vais supprimer ces colonnes. J'ai regardé, mais je n'ai trouvé aucune fonction pour cela. il y en a value_counts, mais ce serait lent pour moi, car la plupart des valeurs sont distinctes et je ne veux que compter NaN.

user3799307
la source

Réponses:

730

Vous pouvez utiliser la isna()méthode (ou son alias isnull()qui est également compatible avec les anciennes versions de pandas <0.21.0) puis additionner pour compter les valeurs NaN. Pour une colonne:

In [1]: s = pd.Series([1,2,3, np.nan, np.nan])

In [4]: s.isna().sum()   # or s.isnull().sum() for older pandas versions
Out[4]: 2

Pour plusieurs colonnes, cela fonctionne aussi:

In [5]: df = pd.DataFrame({'a':[1,2,np.nan], 'b':[np.nan,1,np.nan]})

In [6]: df.isna().sum()
Out[6]:
a    1
b    2
dtype: int64
joris
la source
31
Et si vous voulez le nombre total de nans dans l'ensemble, dfvous pouvez utiliserdf.isnull().sum().sum()
RockJake28
2
Pour obtenir des colonnes, .sum(axis=0)qui est le comportement par défaut. Et pour obtenir rowsums, .sum(axis=1).
smci
1
@ RockJake28 Ordf.isnull().values.sum()
cs95
3
df['column_name'].isna().sum()fonctionne également si quelqu'un se demande.
Superdooperhero
93

Vous pouvez soustraire la longueur totale du nombre de valeurs non nan:

count_nan = len(df) - df.count()

Vous devez le chronométrer sur vos données. Pour les petites séries, la vitesse a été multipliée par 3 par rapport à la isnullsolution.

elyase
la source
4
En effet, mieux vaut le faire. Cela dépendra de la taille du cadre je pense, avec un cadre plus grand (3000 lignes), l'utilisation isnullest déjà deux fois plus rapide que cela.
joris
5
Je l'ai essayé dans les deux sens dans une situation où je comptais la longueur du groupe pour un énorme groupe où les tailles de groupe étaient généralement <4 et où df.isnull (). Sum () de joris était au moins 20 fois plus rapide. C'était avec 0.17.1.
Nathan Lloyd
Pour moi, les deux sont en dessous de 3 ms en moyenne pour 70 000 lignes avec très peu de na.
Josiah Yoder
89

Supposons que dfc'est un DataFrame pandas.

Alors,

df.isnull().sum(axis = 0)

Cela donnera le nombre de valeurs NaN dans chaque colonne.

Si vous avez besoin de valeurs NaN dans chaque ligne,

df.isnull().sum(axis = 1)
rAmAnA
la source
46

Sur la base de la réponse la plus votée, nous pouvons facilement définir une fonction qui nous donne un cadre de données pour prévisualiser les valeurs manquantes et le% de valeurs manquantes dans chaque colonne:

def missing_values_table(df):
        mis_val = df.isnull().sum()
        mis_val_percent = 100 * df.isnull().sum() / len(df)
        mis_val_table = pd.concat([mis_val, mis_val_percent], axis=1)
        mis_val_table_ren_columns = mis_val_table.rename(
        columns = {0 : 'Missing Values', 1 : '% of Total Values'})
        mis_val_table_ren_columns = mis_val_table_ren_columns[
            mis_val_table_ren_columns.iloc[:,1] != 0].sort_values(
        '% of Total Values', ascending=False).round(1)
        print ("Your selected dataframe has " + str(df.shape[1]) + " columns.\n"      
            "There are " + str(mis_val_table_ren_columns.shape[0]) +
              " columns that have missing values.")
        return mis_val_table_ren_columns
Nikos Tavoularis
la source
36

Depuis pandas 0.14.1 ma suggestion ici d'avoir un argument mot-clé dans la méthode value_counts a été implémentée:

import pandas as pd
df = pd.DataFrame({'a':[1,2,np.nan], 'b':[np.nan,1,np.nan]})
for col in df:
    print df[col].value_counts(dropna=False)

2     1
 1     1
NaN    1
dtype: int64
NaN    2
 1     1
dtype: int64
K.-Michael Aye
la source
Meilleure réponse à ce jour, elle permet également de compter d'autres types de valeurs.
gaborous
19

si ses valeurs nan juste en comptant dans une colonne de pandas voici un moyen rapide

import pandas as pd
## df1 as an example data frame 
## col1 name of column for which you want to calculate the nan values
sum(pd.isnull(df1['col1']))
sushmit
la source
2
sushmit, Cette façon n'est pas très rapide si vous avez un certain nombre de colonnes. Dans ce cas, vous devez copier et coller / taper le nom de chaque colonne, puis réexécuter le code.
Amos Long
17

si vous utilisez Jupyter Notebook, que diriez-vous de ....

 %%timeit
 df.isnull().any().any()

ou

 %timeit 
 df.isnull().values.sum()

ou y a-t-il quelque part des NaN dans les données, si oui, où?

 df.isnull().any()
Manoj Kumar
la source
13

Ce qui suit imprimera toutes les colonnes Nan dans l'ordre décroissant.

df.isnull().sum().sort_values(ascending = False)

ou

Ce qui suit imprimera les 15 premières colonnes Nan dans l'ordre décroissant.

df.isnull().sum().sort_values(ascending = False).head(15)
Amar Kumar
la source
10
import numpy as np
import pandas as pd

raw_data = {'first_name': ['Jason', np.nan, 'Tina', 'Jake', 'Amy'], 
        'last_name': ['Miller', np.nan, np.nan, 'Milner', 'Cooze'], 
        'age': [22, np.nan, 23, 24, 25], 
        'sex': ['m', np.nan, 'f', 'm', 'f'], 
        'Test1_Score': [4, np.nan, 0, 0, 0],
        'Test2_Score': [25, np.nan, np.nan, 0, 0]}
results = pd.DataFrame(raw_data, columns = ['first_name', 'last_name', 'age', 'sex', 'Test1_Score', 'Test2_Score'])

results 
'''
  first_name last_name   age  sex  Test1_Score  Test2_Score
0      Jason    Miller  22.0    m          4.0         25.0
1        NaN       NaN   NaN  NaN          NaN          NaN
2       Tina       NaN  23.0    f          0.0          NaN
3       Jake    Milner  24.0    m          0.0          0.0
4        Amy     Cooze  25.0    f          0.0          0.0
'''

Vous pouvez utiliser la fonction suivante, qui vous donnera une sortie dans Dataframe

  • Valeurs nulles
  • Valeurs manquantes
  • % des valeurs totales
  • Total zéro valeur manquante
  • % Total zéro valeurs manquantes
  • Type de données

Copiez et collez simplement la fonction suivante et appelez-la en passant votre pandas Dataframe

def missing_zero_values_table(df):
        zero_val = (df == 0.00).astype(int).sum(axis=0)
        mis_val = df.isnull().sum()
        mis_val_percent = 100 * df.isnull().sum() / len(df)
        mz_table = pd.concat([zero_val, mis_val, mis_val_percent], axis=1)
        mz_table = mz_table.rename(
        columns = {0 : 'Zero Values', 1 : 'Missing Values', 2 : '% of Total Values'})
        mz_table['Total Zero Missing Values'] = mz_table['Zero Values'] + mz_table['Missing Values']
        mz_table['% Total Zero Missing Values'] = 100 * mz_table['Total Zero Missing Values'] / len(df)
        mz_table['Data Type'] = df.dtypes
        mz_table = mz_table[
            mz_table.iloc[:,1] != 0].sort_values(
        '% of Total Values', ascending=False).round(1)
        print ("Your selected dataframe has " + str(df.shape[1]) + " columns and " + str(df.shape[0]) + " Rows.\n"      
            "There are " + str(mz_table.shape[0]) +
              " columns that have missing values.")
#         mz_table.to_excel('D:/sampledata/missing_and_zero_values.xlsx', freeze_panes=(1,0), index = False)
        return mz_table

missing_zero_values_table(results)

Production

Your selected dataframe has 6 columns and 5 Rows.
There are 6 columns that have missing values.

             Zero Values  Missing Values  % of Total Values  Total Zero Missing Values  % Total Zero Missing Values Data Type
last_name              0               2               40.0                          2                         40.0    object
Test2_Score            2               2               40.0                          4                         80.0   float64
first_name             0               1               20.0                          1                         20.0    object
age                    0               1               20.0                          1                         20.0   float64
sex                    0               1               20.0                          1                         20.0    object
Test1_Score            3               1               20.0                          4                         80.0   float64

Si vous voulez rester simple, vous pouvez utiliser la fonction suivante pour obtenir les valeurs manquantes en%

def missing(dff):
    print (round((dff.isnull().sum() * 100/ len(dff)),2).sort_values(ascending=False))


missing(results)
'''
Test2_Score    40.0
last_name      40.0
Test1_Score    20.0
sex            20.0
age            20.0
first_name     20.0
dtype: float64
'''
Suhas_Pote
la source
10

Pour compter les zéros:

df[df == 0].count(axis=0)

Pour compter NaN:

df.isnull().sum()

ou

df.isna().sum()
Pygirl
la source
9

Veuillez utiliser ci-dessous pour le nombre de colonnes particulier

dataframe.columnName.isnull().sum()
Anurag Bhakuni
la source
8

Vous pouvez utiliser la méthode value_counts et imprimer les valeurs de np.nan

s.value_counts(dropna = False)[np.nan]
Itachi
la source
Agréable! Celui-ci est le plus utile si vous souhaitez compter à la fois les NaN et les non-NaN. s.value_counts(dropna = False)
icemtel
3
df1.isnull().sum()

Ça fera l'affaire.

Naveen Bharadwaj
la source
3

Voici le code pour compter les Nullvaleurs par colonne:

df.isna().sum()
Sanket
la source
3

Il y a un bel article Dzone de juillet 2017 qui détaille diverses façons de résumer les valeurs NaN. Découvrez-le ici .

L'article que j'ai cité fournit une valeur supplémentaire en: (1) montrant un moyen de compter et d'afficher les nombres de NaN pour chaque colonne afin que l'on puisse facilement décider de supprimer ou non ces colonnes et (2) de montrer un moyen de sélectionner ces lignes dans spécifiques qui ont des NaN afin qu'ils puissent être sélectivement rejetés ou imputés.

Voici un exemple rapide pour démontrer l'utilité de l'approche - avec seulement quelques colonnes, son utilité n'est peut-être pas évidente mais je l'ai trouvée utile pour des trames de données plus grandes.

import pandas as pd
import numpy as np

# example DataFrame
df = pd.DataFrame({'a':[1,2,np.nan], 'b':[np.nan,1,np.nan]})

# Check whether there are null values in columns
null_columns = df.columns[df.isnull().any()]
print(df[null_columns].isnull().sum())

# One can follow along further per the cited article
moyenne
la source
3

Une autre option simple qui n'est pas encore suggérée, pour ne compter que les NaN, serait d'ajouter la forme pour renvoyer le nombre de lignes avec NaN.

df[df['col_name'].isnull()]['col_name'].shape
SlipperyD
la source
2

df.isnull (). sum () donnera la somme des valeurs manquantes par colonne.

Si vous voulez connaître la somme des valeurs manquantes dans une colonne particulière, le code suivant fonctionnera df.column.isnull (). Sum ()

K Pradeep Kumar Reddy
la source
1

basé sur la réponse qui a été donnée et quelques améliorations c'est mon approche

def PercentageMissin(Dataset):
    """this function will return the percentage of missing values in a dataset """
    if isinstance(Dataset,pd.DataFrame):
        adict={} #a dictionary conatin keys columns names and values percentage of missin value in the columns
        for col in Dataset.columns:
            adict[col]=(np.count_nonzero(Dataset[col].isnull())*100)/len(Dataset[col])
        return pd.DataFrame(adict,index=['% of missing'],columns=adict.keys())
    else:
        raise TypeError("can only be used with panda dataframe")
Espoir Murhabazi
la source
Je préfèredf.apply(lambda x: x.value_counts(dropna=False)[np.nan]/x.size*100)
K.-Michael Aye
1

Dans le cas où vous devez obtenir les chiffres non-NA (non-None) et NA (None) pour différents groupes, retirés par groupby:

gdf = df.groupby(['ColumnToGroupBy'])

def countna(x):
    return (x.isna()).sum()

gdf.agg(['count', countna, 'size'])

Cela renvoie le nombre de non-NA, NA et le nombre total d'entrées par groupe.

aysa
la source
0

J'ai utilisé la solution proposée par @sushmit dans mon code.

Une variation possible de la même chose peut également être

colNullCnt = []
for z in range(len(df1.cols)):
    colNullCnt.append([df1.cols[z], sum(pd.isnull(trainPd[df1.cols[z]]))])

L'avantage est qu'il renvoie désormais le résultat pour chacune des colonnes du df.

vsdaking
la source
0
import pandas as pd
import numpy as np

# example DataFrame
df = pd.DataFrame({'a':[1,2,np.nan], 'b':[np.nan,1,np.nan]})

# count the NaNs in a column
num_nan_a = df.loc[ (pd.isna(df['a'])) , 'a' ].shape[0]
num_nan_b = df.loc[ (pd.isna(df['b'])) , 'b' ].shape[0]

# summarize the num_nan_b
print(df)
print(' ')
print(f"There are {num_nan_a} NaNs in column a")
print(f"There are {num_nan_b} NaNs in column b")

Donne en sortie:

     a    b
0  1.0  NaN
1  2.0  1.0
2  NaN  NaN

There are 1 NaNs in column a
There are 2 NaNs in column b
Arjaan Buijk
la source
0

Supposons que vous souhaitiez obtenir le nombre de valeurs manquantes (NaN) dans une colonne (série) appelée prix dans une trame de données appelée avis

#import the dataframe
import pandas as pd

reviews = pd.read_csv("../input/wine-reviews/winemag-data-130k-v2.csv", index_col=0)

Pour obtenir les valeurs manquantes, avec n_missing_prices comme variable, faites simplement

n_missing_prices = sum(reviews.price.isnull())
print(n_missing_prices)

sum est la méthode clé ici, j'essayais d'utiliser count avant de réaliser que sum était la bonne méthode à utiliser dans ce contexte

John R
la source
-1

Pour votre tâche, vous pouvez utiliser pandas.DataFrame.dropna ( https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.dropna.html ):

import pandas as pd
import numpy as np

df = pd.DataFrame({'a': [1, 2, 3, 4, np.nan],
                   'b': [1, 2, np.nan, 4, np.nan],
                   'c': [np.nan, 2, np.nan, 4, np.nan]})
df = df.dropna(axis='columns', thresh=3)

print(df)

Avec le paramètre Thresh, vous pouvez déclarer le nombre maximal de valeurs NaN pour toutes les colonnes dans DataFrame.

Sorties de code:

     a    b
0  1.0  1.0
1  2.0  2.0
2  3.0  NaN
3  4.0  4.0
4  NaN  NaN
Anastasia Didan
la source