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


464

Tengo datos, en los que quiero encontrar el número NaN, de modo que si es inferior a algún umbral, eliminaré estas columnas. Miré, pero no pude encontrar ninguna función para esto. lo hay value_counts, pero sería lento para mí, porque la mayoría de los valores son distintos y NaNsolo quiero contarlos .

Respuestas:


730

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

31
Y si quieres el número total de nans en total df, puedes usarlodf.isnull().sum().sum()
RockJake28

2
Para obtener colsums, .sum(axis=0)que es el comportamiento predeterminado. Y para conseguir rowsums, .sum(axis=1).
smci

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

3
df['column_name'].isna().sum()También funciona si alguien se pregunta.
Superdooperhero

93

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

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

Debe cronometrarlo en sus datos. Para las series pequeñas, se aceleró 3 veces en comparación con la isnullsolución.


44
De hecho, mejor momento. Creo que dependerá del tamaño del marco, con un marco más grande (3000 filas), el uso isnullya es dos veces más rápido.
joris

55
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 generalmente eran <4, y joris 'df.isnull (). Sum () era al menos 20 veces más rápido. Esto fue con 0.17.1.
Nathan Lloyd

Para mí, ambos tienen menos de 3 ms de promedio para 70,000 filas con muy pocas na.
Josiah Yoder

89

Supongamos que dfes un DataFrame de pandas.

Entonces,

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

Esto le dará una cantidad de valores de NaN en cada columna.

Si lo necesita, valores NaN en cada fila,

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

46

Según la respuesta más votada, podemos definir fácilmente una función que nos proporciona un marco de datos para obtener una vista previa de los valores faltantes y el% de valores faltantes 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

36

Desde pandas 0.14.1 mi sugerencia aquí para tener un argumento de palabra clave en el método value_counts se ha implementado:

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 mejor respuesta hasta ahora, permite contar también otros tipos de valores.
Gaborous

19

si solo está contando valores nan en una columna de pandas aquí es una forma 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, de esta manera no es muy rápido si tienes 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

17

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

13

Lo siguiente imprimirá todas las columnas Nan en orden descendente.

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

o

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

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

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

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

Simplemente copie y pegue la siguiente función y llámela pasando el marco de datos de sus 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)

Salida

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

10

Para contar ceros:

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

Para contar NaN:

df.isnull().sum()

o

df.isna().sum()

9

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

dataframe.columnName.isnull().sum()

8

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

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

¡Agradable! Este es el más útil si desea contar tanto NaN como no NaN. s.value_counts(dropna = False)
icemtel


3

Aquí está el código para contar Nullvalores en 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 descartarse o imputarse 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 descubrí que es ú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

3

Otra opción simple que aún no se sugiere, 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

2

df.isnull (). sum () dará la suma de valores perdidos en columna.

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


1

basado en la respuesta dada 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")

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

1

En caso de que necesite obtener los recuentos no NA (no Ninguno) y NA (Ninguno) en los 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 del mismo 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 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 el número de valores faltantes (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



-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 de umbral, puede declarar el recuento máximo de los valores de 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
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.