如何在pandas DataFrame中计算一列中的NaN值数量?

788
我想要找到我的数据中每一列的 NaN 数量。

我正在搜索“如何计算列中的NaN值”,但实际上答案是针对“我想找到数据每列中NaN的数量”。幸运的是,其中一条评论提供了答案。典型的“标题与正文不符,因此答案也不符合标题”。 - mins
1
@Rishabh 注意,df.info()不会返回一个DataFrame,该方法只是打印信息。 - joris
1
谢谢@joris - 只需简单的df.info()即可提供每列的数据类型和非空计数。 - Rishabh
32个回答

3
有一篇来自2017年7月的Dzone文章,详细介绍了各种总结NaN值的方法。你可以在这里查看。
引用的这篇文章提供了额外的价值:(1)展示了一种计算和显示每列NaN计数的方法,以便人们可以轻松地决定是否舍弃这些列;(2)演示了一种选择具有NaN值的特定行的方法,以便对它们进行有选择性的舍弃或插补。
下面是一个快速的例子来演示这种方法的实用性——也许对于只有几列的数据框来说,它的用处不是很明显,但我发现它对于更大的数据框非常有帮助。
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

2

如果你需要通过groupby获取不是NA(非None)和NA(None)的计数,请按如下方式操作:

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

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

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

此函数返回每个组的非NA计数、NA计数和总条目数。


1
我使用这个循环来计算每列的缺失值:
# check missing values
import numpy as np, pandas as pd
for col in df:
      print(col +': '+ np.str(df[col].isna().sum()))

1
你可以使用df.iteritems()遍历数据框。在for循环中设置条件来计算每列的NaN值百分比,并丢弃那些包含NaN值超过你设定阈值的列:
for col, val in df.iteritems():
    if (df[col].isnull().sum() / len(val) * 100) > 30:
        df.drop(columns=col, inplace=True)

1

根据给出的答案和一些改进,这是我的方法。

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
我更喜欢 df.apply(lambda x: x.value_counts(dropna=False)[np.nan]/x.size*100) - K.-Michael Aye

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

输出结果为:

     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
另一种完整性考虑的方法是使用 np.count_nonzero 和 .isna():
np.count_nonzero(df.isna())

%timeit np.count_nonzero(df.isna())
512 ms ± 24.7 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

与使用1000005行×16列数据框的顶级答案相比:

%timeit df.isna().sum()
492 ms ± 55.2 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

%timeit df.isnull().sum(axis = 0)
478 ms ± 34.9 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

%timeit count_nan = len(df) - df.count()
484 ms ± 47.4 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

数据:

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

# big dataframe for %timeit 
big_df = pd.DataFrame(np.random.randint(0, 100, size=(1000000, 10)), columns=list('ABCDEFGHIJ'))
df = pd.concat([big_df,results]) # 1000005 rows × 16 columns

0
我写了一个简短的函数(Python 3),用于生成一个pandas数据框,可以将其写入Excel中的.info文件:
df1 = pd.DataFrame({'a':[1,2,np.nan], 'b':[np.nan,1,np.nan]}) 
def info_as_df (df):
    null_counts = df.isna().sum()
    info_df = pd.DataFrame(list(zip(null_counts.index,null_counts.values))\
                                         , columns = ['Column', 'Nulls_Count'])
    data_types = df.dtypes
    info_df['Dtype'] = data_types.values
    return info_df
print(df1.info())
print(info_as_df(df1))

这将会给出:

<class 'pandas.core.frame.DataFrame'>
RangeIndex: 3 entries, 0 to 2
Data columns (total 2 columns):
 #   Column  Non-Null Count  Dtype  
---  ------  --------------  -----  
 0   a       2 non-null      float64
 1   b       1 non-null      float64
dtypes: float64(2)
memory usage: 176.0 bytes
None
  Column  Nulls_Count    Dtype
0      a            1  float64
1      b            2  float64

0
假设你想要获取数据框reviews中名为price的列(series)中缺失值(NaN)的数量。
#import the dataframe
import pandas as pd

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

要获取缺失的值,使用变量n_missing_prices,只需执行以下操作

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

这里的关键方法是sum,之前尝试使用count,但意识到在这种情况下使用sum才是正确的方法。


0

在我的代码中使用了@sushmit提出的解决方案。

同样的,还有可能有一种变化。

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

这样做的优点是,它会返回数据框中每列的结果。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接