Como contar os valores de NaN em uma coluna no DataFrame do pandas


461

Eu tenho dados, nos quais eu quero encontrar o número de NaN, para que, se for menor que algum limite, eu soltarei essas colunas. Eu olhei, mas não consegui encontrar nenhuma função para isso. existe value_counts, mas seria lento para mim, porque a maioria dos valores é distinta e eu quero NaNapenas contar .

Respostas:


730

Você pode usar o isna()método (ou seu apelido, isnull()que também é compatível com versões anteriores do pandas <0.21.0) e depois somar para contar os valores de NaN. Para uma coluna:

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

Para várias colunas, também funciona:

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 você quiser o número total de nans em toda dfvocê pode usardf.isnull().sum().sum()
RockJake28

2
Para obter colsums, .sum(axis=0)qual é o comportamento padrão. E para obter linhas de linhas .sum(axis=1).
smci 28/05/19

1
@ RockJake28 Oudf.isnull().values.sum()
cs95

3
df['column_name'].isna().sum()também funciona se alguém está se perguntando.
Superdooperhero 12/07/19

93

Você pode subtrair o comprimento total da contagem de valores que não são nan:

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

Você deve cronometrar seus dados. Para séries pequenas, a velocidade é 3x em comparação com a isnullsolução.


4
Na verdade, melhor hora. Depende do tamanho do quadro, eu acho, com um quadro maior (3000 linhas), o uso isnulljá é duas vezes mais rápido que isso.
Joris

5
Eu tentei nos dois sentidos em uma situação em que eu estava contando o comprimento do grupo para um grupo enorme, onde os tamanhos dos grupos eram geralmente <4, e joris 'df.isnull (). Sum () era pelo menos 20x mais rápido. Isso foi com 0.17.1.
Nathan Lloyd

Para mim, ambos têm menos de 3ms de média para 70.000 linhas com muito poucos na's.
Josiah Yoder

89

Vamos supor que dfseja um DataFrame de pandas.

Então,

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

Isso fornecerá o número de valores de NaN em todas as colunas.

Se você precisar, valores de NaN em todas as linhas,

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

46

Com base na resposta mais votada, podemos definir facilmente uma função que nos fornece um quadro de dados para visualizar os valores ausentes e a porcentagem de valores ausentes em cada coluna:

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

Desde o pandas 0.14.1, minha sugestão aqui para ter um argumento de palavra-chave no método value_counts foi implementada:

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

Melhor resposta até agora, permite contar também outros tipos de valores.
gaborous

19

se apenas contando os valores nan em uma coluna de pandas aqui é uma maneira rápida

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, Dessa forma, não é muito rápido se você tiver um número de colunas. Nesse caso, você teria que copiar e colar / digitar o nome de cada coluna e depois executar novamente o código.
Amos Longo

17

Se você estiver usando o Jupyter Notebook, que tal ....

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

ou

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

ou há algum NaNs nos dados; se sim, onde?

 df.isnull().any()

13

O abaixo imprimirá todas as colunas Nan em ordem decrescente.

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

ou

O abaixo imprimirá as primeiras 15 colunas Nan em ordem 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
'''

Você pode usar a seguinte função, que fornecerá saída no Dataframe

  • Zero Values
  • Valores em falta
  • % do total de valores
  • Total de valores ausentes em zero
  • % Total de zero valores ausentes
  • Tipo de dados

Basta copiar e colar a seguinte função e chamá-la passando o Dataframe do seu panda

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)

Resultado

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 você deseja simplificar, pode usar a seguinte função para obter valores ausentes em%

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

Para contar zeros:

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

Para contar NaN:

df.isnull().sum()

ou

df.isna().sum()

8

Você pode usar o método value_counts e imprimir valores de np.nan

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

Agradável! Este é o mais útil se você deseja contar NaNs e não NaNs. s.value_counts(dropna = False)
icemtel 5/09/19

8

Use abaixo para uma contagem específica de colunas

dataframe.columnName.isnull().sum()


3

Aqui está o código para contar Nullvalores na coluna:

df.isna().sum()

3

Há um bom artigo do Dzone de julho de 2017 que detalha várias maneiras de resumir os valores de NaN. Confira aqui .

O artigo que citei fornece um valor adicional: (1) Mostrando uma maneira de contar e exibir as contagens de NaN para cada coluna, para que você possa decidir facilmente se deve ou não descartar essas colunas; (2) Demonstrando uma maneira de selecionar essas linhas em específicos que possuem NaNs para que possam ser descartados ou imputados seletivamente.

Aqui está um exemplo rápido para demonstrar a utilidade da abordagem - com apenas algumas colunas, talvez sua utilidade não seja óbvia, mas achei que seria útil para quadros de dados maiores.

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

Uma outra opção simples ainda não sugerida, apenas para contar NaNs, seria adicionar a forma para retornar o número de linhas com NaN.

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

2

df.isnull (). sum () fornecerá a soma em coluna dos valores ausentes.

Se você deseja saber a soma dos valores ausentes em uma coluna específica, o código a seguir funcionará df.column.isnull (). Sum ()


1

com base na resposta que foi dada e algumas melhorias, esta é a minha abordagem

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

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

1

Caso você precise obter as contagens não-NA (não-Nenhuma) e NA (Nenhuma) entre os diferentes grupos, retiradas por grupo por:

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

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

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

Isso retorna as contagens de não NA, NA e número total de entradas por grupo.


0

Usei a solução proposta por @sushmit no meu código.

Uma possível variação do mesmo também pode ser

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

A vantagem disso é que ele retorna o resultado para cada uma das colunas no df a partir de agora.


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

Dá como saída:

     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

Suponha que você queira obter o número de valores ausentes (NaN) em uma coluna (série) conhecida como preço em um dataframe chamado reviews

#import the dataframe
import pandas as pd

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

Para obter os valores ausentes, com n_missing_prices como a variável, faça

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

sum é o método-chave aqui, estava tentando usar count antes que eu percebesse que sum é o método certo a ser usado neste contexto



-1

Para sua tarefa, você pode usar 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)

Com o parâmetro thresh, você pode declarar a contagem máxima de valores de NaN para todas as colunas no DataFrame.

Saídas de código:

     a    b
0  1.0  1.0
1  2.0  2.0
2  3.0  NaN
3  4.0  4.0
4  NaN  NaN
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.