Come contare i valori NaN in una colonna in Panda DataFrame


463

Ho dei dati, in cui voglio trovare il numero di NaN, in modo che se è inferiore a qualche soglia, lascerò cadere queste colonne. Ho guardato, ma non sono riuscito a trovare alcuna funzione per questo. c'è value_counts, ma sarebbe lento per me, perché la maggior parte dei valori sono distinti e voglio NaNsolo contare .

Risposte:


730

Puoi usare il isna()metodo (o il suo alias isnull()che è anche compatibile con le versioni precedenti di Panda <0.21.0) e quindi sommare per contare i valori NaN. Per una colonna:

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

Per diverse colonne, funziona anche:

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

31
E se vuoi il numero totale di nans nel complesso dfpuoi usaredf.isnull().sum().sum()
RockJake28

2
Per ottenere Colosseo, .sum(axis=0)che è il comportamento predefinito. E per ottenere rowsums, .sum(axis=1).
smci,

1
@ RockJake28 Oppuredf.isnull().values.sum()
cs95,

3
df['column_name'].isna().sum()funziona anche se qualcuno si sta chiedendo.
Superdooperhero,

93

È possibile sottrarre la lunghezza totale dal conteggio di valori non nan:

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

Dovresti cronometrarlo sui tuoi dati. Per le piccole serie ha una velocità 3x rispetto alla isnullsoluzione.


4
Anzi, è il momento migliore. Dipende dalla dimensione del frame, penso, con un frame più grande (3000 righe), l'utilizzo isnullè già due volte più veloce di così.
joris,

5
Ho provato in entrambi i modi in una situazione in cui stavo contando la lunghezza del gruppo per un gruppo enorme in cui le dimensioni del gruppo erano generalmente <4 e jfis 'df.isnull (). Sum () era almeno 20 volte più veloce. Questo era con 0.17.1.
Nathan Lloyd,

Per me, entrambi hanno una media inferiore a 3 ms per 70.000 file con pochissimi na.
Josiah Yoder,

89

Supponiamo che dfsia un DataFrame Panda.

Poi,

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

Ciò fornirà il numero di valori NaN in ogni colonna.

Se necessario, i valori NaN in ogni riga,

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

46

Sulla base della risposta più votata possiamo facilmente definire una funzione che ci fornisce un frame di dati per visualizzare in anteprima i valori mancanti e la percentuale di valori mancanti in ogni colonna:

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

36

Da Panda 0.14.1 il mio suggerimento qui di avere un argomento di parole chiave nel metodo value_counts è stato implementato:

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

La migliore risposta finora, consente di contare anche altri tipi di valori.
Gaborous

19

se sta solo contando i valori di nan in una colonna di Panda qui è un modo rapido

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']))

2
sushmit, In questo modo non è molto veloce se hai un numero di colonne. In tal caso, dovresti copiare e incollare / digitare il nome di ogni colonna, quindi rieseguire il codice.
Amos Long,

17

se stai usando Jupyter Notebook, che ne dici di ...

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

o

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

oppure, ci sono dei NaN nei dati, se sì, dove?

 df.isnull().any()

13

Di seguito verranno stampate tutte le colonne Nan in ordine decrescente.

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

o

Di seguito verranno stampate le prime 15 colonne Nan in ordine decrescente.

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

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
'''

Puoi usare la seguente funzione, che ti darà l'output in Dataframe

  • Valori zero
  • Valori mancanti
  • % dei valori totali
  • Totale zero valori mancanti
  • % Totale zero valori mancanti
  • Tipo di dati

Basta copiare e incollare la seguente funzione e chiamarla passando il tuo panda 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)

Produzione

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

Se vuoi mantenerlo semplice, puoi usare la seguente funzione per ottenere valori mancanti in%

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
'''

10

Per contare gli zeri:

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

Per contare NaN:

df.isnull().sum()

o

df.isna().sum()

8

È possibile utilizzare il metodo value_counts e stampare i valori di np.nan

s.value_counts(dropna = False)[np.nan]

Bello! Questo è il più utile se si desidera contare sia NaN che non NaN. s.value_counts(dropna = False)
Icemtel,

8

Si prega di utilizzare di seguito per il conteggio delle colonne particolari

dataframe.columnName.isnull().sum()


3

Ecco il codice per il conteggio dei Nullvalori nella colonna saggia:

df.isna().sum()

3

C'è un bell'articolo Dzone di luglio 2017 che descrive in dettaglio vari modi di riassumere i valori di NaN. Dai un'occhiata qui .

L'articolo che ho citato fornisce un valore aggiuntivo tramite: (1) Mostra un modo per contare e visualizzare i conteggi NaN per ogni colonna in modo che si possa facilmente decidere se scartare o meno quelle colonne e (2) Dimostrare un modo per selezionare quelle righe in specifici che hanno NaN in modo che possano essere scartati o imputati selettivamente.

Ecco un breve esempio per dimostrare l'utilità dell'approccio - con solo poche colonne forse la sua utilità non è ovvia, ma ho trovato che fosse di aiuto per frame di dati più grandi.

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

3

Un'altra semplice opzione non ancora suggerita, per contare solo NaN, sarebbe l'aggiunta nella forma per restituire il numero di righe con NaN.

df[df['col_name'].isnull()]['col_name'].shape

2

df.isnull (). sum () fornirà la somma per colonna dei valori mancanti.

Se vuoi conoscere la somma dei valori mancanti in una particolare colonna, il codice seguente funzionerà df.column.isnull (). Sum ()


1

basato sulla risposta che è stata data e alcuni miglioramenti questo è il mio approccio

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")

Preferiscodf.apply(lambda x: x.value_counts(dropna=False)[np.nan]/x.size*100)
K.-Michael Aye il

1

Nel caso in cui sia necessario ottenere i conteggi non NA (non Nessuno) e NA (Nessuno) tra diversi gruppi estratti da groupby:

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

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

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

Ciò restituisce i conteggi di non NA, NA e il numero totale di voci per gruppo.


0

Ho usato la soluzione proposta da @sushmit nel mio codice.

Una possibile variazione della stessa può anche essere

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

Il vantaggio di ciò è che restituisce il risultato per ciascuna delle colonne nel df d'ora in poi.


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")

Fornisce come output:

     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

0

Supponiamo di voler ottenere il numero di valori mancanti (NaN) in una colonna (serie) nota come prezzo in un frame di dati chiamato recensioni

#import the dataframe
import pandas as pd

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

Per ottenere i valori mancanti, con n_missing_prices come variabile, fare semplicemente

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

La somma è il metodo chiave qui, stavo cercando di usare il conteggio prima che mi rendessi conto che la somma è il metodo giusto da usare in questo contesto



-1

Per il tuo compito puoi usare 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)

Con questo parametro è possibile dichiarare il conteggio massimo per i valori NaN per tutte le colonne in DataFrame.

Uscite di codice:

     a    b
0  1.0  1.0
1  2.0  2.0
2  3.0  NaN
3  4.0  4.0
4  NaN  NaN
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.