Cómo contar los valores de NaN en una columna en pandas DataFrame

626

Quiero encontrar el número de NaNen cada columna de mis datos para poder eliminar una columna si tiene menos NaNde algún umbral. Busqué pero no pude encontrar ninguna función para esto. value_countses demasiado lento para mí porque la mayoría de los valores son distintos y solo me interesa el NaNrecuento.

3
  • Estaba buscando " Cómo contar los valores de NaN en una columna ", pero en realidad las respuestas son para " Quiero encontrar el número de NaN en cada columna de mis datos ". Afortunadamente, uno de los comentarios proporciona la respuesta. Típico "el cuerpo no coincide con el título y, por lo tanto, las respuestas no coinciden con el título". mins 30 dic.20 a las 11:30
  • 1
    @Rishabh tenga en cuenta que df.info()no devuelve un DataFame, el método solo imprime la información. joris 9 de junio a las 6:47
  • Gracias @joris - Solo un simple df.info()dará los tipos de datos y recuentos no nulos para cada columnaRishabh 9 de junio a las 9:28
926

Puede usar el isna()método (o su alias, isnull()que también es compatible con versiones anteriores de pandas <0.21.0) y luego sumar para contar los valores de NaN. Para una columna:

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 varias columnas, también 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
7
  • 50
    Y si desea el número total de nans en total df, puede usardf.isnull().sum().sum()JakeCowton 8 de mayo de 2017 a las 0:26
  • 6
    Para obtener colsums, .sum(axis=0)que es el comportamiento predeterminado. Y para conseguir rowsums, .sum(axis=1). smci 28 de mayo de 2019 a las 7:57
  • 3
    @ RockJake28 Odf.isnull().values.sum()cs95 21/06/19 a las 16:50
  • dieciséis
    df['column_name'].isna().sum()también funciona si alguien se lo pregunta. Superdooperhero 12/07/19 a las 17:33
  • 2
    " y luego sumar para contar los valores de NaN ", para entender esta declaración, es necesario entender df.isna()produce Serie booleana donde el número de Truees el número de NaN, y los df.isna().sum()suma Falsey Truereemplaza respectivamente por 0 y 1. Por lo tanto, esto cuenta indirectamente el NaN, donde un simple countsimplemente devolvería la longitud de la columna. mins 30/12/20 a las 11:47
130

Supongamos que dfes un DataFrame de pandas.

Luego,

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

Esto dará un número de valores de NaN en cada columna.

Si lo necesita, valores de NaN en cada fila,

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

Puede restar la longitud total del recuento de valores que no sean nan:

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

Debe sincronizarlo con sus datos. Para las series pequeñas, se obtuvo una velocidad 3 veces mayor en comparación con la isnullsolución.

3
  • 6
    De hecho, mejor momento. Dependerá del tamaño del marco, creo, con un marco más grande (3000 filas), el uso isnullya es dos veces más rápido que este. joris 8/10/2014 a las 21:12
  • 6
    Lo intenté en ambos sentidos en una situación en la que estaba contando la longitud del grupo para un grupo enorme, donde los tamaños de grupo eran generalmente <4, y el df.isnull (). Sum () de joris era al menos 20 veces más rápido. Esto fue con 0.17.1. Nathan Lloyd 16 de marzo de 2016 a las 16:49
  • Para mí, ambos tienen un promedio de menos de 3 ms para 70,000 filas con muy pocas na. Josiah Yoder 2 de julio de 2018 a las 17:03
60

Basándonos en la respuesta más votada, podemos definir fácilmente una función que nos da un marco de datos para obtener una vista previa de los valores perdidos y el% de valores perdidos en cada columna:

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
1
  • 3
    algo similar como df.stb.missing ()? ¡Tendrá que importar el módulo de tabla lateral para que esto funcione! shantanuo 12 de enero a las 9:25
40

Desde pandas 0.14.1, se implementó mi sugerencia aquí de tener un argumento de palabra clave en el método value_counts:

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
1
  • La mejor respuesta hasta ahora, permite contar también otros tipos de valores. gaborous 17 de febrero de 2018 a las 2:46
26

A continuación, se imprimirán todas las columnas de Nan en orden descendente.

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

o

A continuación, se imprimirán las primeras 15 columnas Nan en orden descendente.

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

si solo está contando los valores nan en una columna de pandas, aquí hay una manera 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']))
1
  • 3
    sushmit, esta forma no es muy rápida si tiene varias columnas. En ese caso, tendría que copiar y pegar / escribir el nombre de cada columna, luego volver a ejecutar el código. Amos Long 21/06/18 a las 12:15
22

df.isnull().sum() dará la suma de los valores perdidos por columnas.

Si desea saber la suma de los valores faltantes en una columna en particular, el siguiente código funcionará: df.column.isnull().sum()

18

si está utilizando Jupyter Notebook, ¿qué tal ...

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

o

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

o, ¿hay algún NaN en los datos? En caso afirmativo, ¿dónde?

 df.isnull().any()
17
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
'''

Puede usar la siguiente función, que le dará una salida en Dataframe

  • Valores cero
  • Valores faltantes
  • % de valores totales
  • Valores perdidos de cero totales
  • % De valores perdidos de cero totales
  • Tipo de datos

Simplemente copie y pegue la siguiente función y llámela pasando su marco de datos de pandas

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)

Producción

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 desea mantenerlo simple, puede usar la siguiente función para obtener los valores faltantes 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
'''
0
16

Utilice a continuación para el recuento de columnas en particular

dataframe.columnName.isnull().sum()
14

Para contar ceros:

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

Para contar NaN:

df.isnull().sum()

o

df.isna().sum()
13

Espero que esto ayude,

import pandas as pd
import numpy as np
df = pd.DataFrame({'a':[1,2,np.nan], 'b':[np.nan,1,np.nan],'c':[np.nan,2,np.nan], 'd':[np.nan,np.nan,np.nan]})

ingrese la descripción de la imagen aquí

df.isnull().sum()/len(df) * 100

ingrese la descripción de la imagen aquí

Thres = 40
(df.isnull().sum()/len(df) * 100 ) < Thres

ingrese la descripción de la imagen aquí

13
df.isnull().sum() 
      //type: <class 'pandas.core.series.Series'>

o

df.column_name.isnull().sum()
     //type: <type 'numpy.int64'>
10

Puede utilizar el método value_counts e imprimir valores de np.nan

s.value_counts(dropna = False)[np.nan]
1
  • ¡Bonito! Este es el más útil si desea contar tanto NaN como no NaN. s.value_counts(dropna = False)icemtel 5 de septiembre de 2019 a las 8:36
4

Otra opción simple aún no sugerida, para contar los NaN, sería agregar la forma para devolver el número de filas con NaN.

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

Para el recuento de la primera parte NaNtenemos múltiples formas.

Método 1 count, debido a countque ignorará NaNcuál es diferente desize

print(len(df) - df.count())

Método 2 isnull/ isnacadena consum

print(df.isnull().sum())
#print(df.isna().sum())

Método 3 describe/ info: observe que esto generará el recuento de valores 'notnull'

print(df.describe())
#print(df.info())

Método de numpy

print(np.count_nonzero(np.isnan(df.values),axis=0))

Para la segunda parte de la pregunta, si quisiéramos dejar caer la columna por el umbral, podemos probar condropna

thresh, optional Require that many non-NA values.

Thresh = n # no null value require, you can also get the by int(x% * len(df))
df = df.dropna(thresh = Thresh, axis = 1)
3
df1.isnull().sum()

Esto hará el truco.

3

Aquí está el código para contar los Nullvalores de columna:

df.isna().sum()
3

Hay un buen artículo de Dzone de julio de 2017 que detalla varias formas de resumir los valores de NaN. Compruébalo aquí .

El artículo que he citado proporciona un valor adicional al: (1) Mostrar una forma de contar y mostrar los recuentos de NaN para cada columna para que uno pueda decidir fácilmente si descartar o no esas columnas y (2) Demostrar una forma de seleccionar esas filas en específicos que tienen NaN para que puedan ser descartados o imputados selectivamente.

Aquí hay un ejemplo rápido para demostrar la utilidad del enfoque: con solo unas pocas columnas, tal vez su utilidad no sea obvia, pero me pareció útil para marcos de datos más 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
1

basado en la respuesta que se dio y algunas mejoras, este es mi enfoque

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")
1
  • 1
    Yo prefierodf.apply(lambda x: x.value_counts(dropna=False)[np.nan]/x.size*100)K.-Michael Aye 7/04/18 a las 17:47
1

En caso de que necesite obtener los recuentos de no NA (no Ninguno) y NA (Ninguno) en diferentes grupos extraídos por groupby:

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

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

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

Esto devuelve los recuentos de no NA, NA y el número total de entradas por grupo.

0

Usé la solución propuesta por @sushmit en mi código.

Una posible variación de la misma también puede ser

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

La ventaja de esto es que devuelve el resultado para cada una de las columnas en el df de ahora en adelante.

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

Da como salida:

     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

Suponga que desea obtener la cantidad de valores perdidos (NaN) en una columna (serie) conocida como precio en un marco de datos llamado revisiones

#import the dataframe
import pandas as pd

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

Para obtener los valores faltantes, con n_missing_prices como variable, simplemente haga

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

sum es el método clave aquí, estaba tratando de usar count antes de darme cuenta de que sum es el método correcto para usar en este contexto

0

Utilizo este ciclo para contar los valores faltantes para cada columna:

# check missing values
import numpy as np, pandas as pd
for col in df:
      print(col +': '+ np.str(df[col].isna().sum()))
-1

Para su tarea, puede 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)

Con el parámetro Thresh, puede declarar el recuento máximo de valores NaN para todas las columnas en DataFrame.

Salidas 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
-1

Una solución es encontrar filas de valor nulo y convertirlas en un marco de datos y luego verificar la longitud del nuevo marco de datos.

nan_rows = df[df['column_name'].isnull()]
print(len(nan_rows))
-2

https://pandas.pydata.org/pandas-docs/stable/generated/pandas.Series.count.html#pandas.Series.count

pandas.Series.count
Series.count(level=None)[source]

Devuelve el número de observaciones nulas / no NA en la serie

1
  • La pregunta es sobre el número de valores NA / nulos y no al revés. burny 18 mar.20 a las 16:00