如何按“pandas”中的列获取缺失/NaN 数据的汇总计数?

问题描述 投票:0回答:11

R 中,我可以使用

summary
命令快速查看丢失数据的计数,但等效的
pandas
DataFrame 方法,
describe
不会报告这些值。

我想我可以做类似的事情

len(mydata.index) - mydata.count()

计算每列的缺失值数量,但我想知道是否有更好的习惯用法(或者我的方法是否正确)。

pandas reporting nan missing-data
11个回答
59
投票

describe
info
都报告非缺失值的计数。

In [1]: df = DataFrame(np.random.randn(10,2))

In [2]: df.iloc[3:6,0] = np.nan

In [3]: df
Out[3]: 
          0         1
0 -0.560342  1.862640
1 -1.237742  0.596384
2  0.603539 -1.561594
3       NaN  3.018954
4       NaN -0.046759
5       NaN  0.480158
6  0.113200 -0.911159
7  0.990895  0.612990
8  0.668534 -0.701769
9 -0.607247 -0.489427

[10 rows x 2 columns]

In [4]: df.describe()
Out[4]: 
              0          1
count  7.000000  10.000000
mean  -0.004166   0.286042
std    0.818586   1.363422
min   -1.237742  -1.561594
25%   -0.583795  -0.648684
50%    0.113200   0.216699
75%    0.636036   0.608839
max    0.990895   3.018954

[8 rows x 2 columns]


In [5]: df.info()
<class 'pandas.core.frame.DataFrame'>
Int64Index: 10 entries, 0 to 9
Data columns (total 2 columns):
0    7 non-null float64
1    10 non-null float64
dtypes: float64(2)

要计算失踪人数,您的解决方案是正确的

In [20]: len(df.index)-df.count()
Out[20]: 
0    3
1    0
dtype: int64

你也可以这么做

In [23]: df.isnull().sum()
Out[23]: 
0    3
1    0
dtype: int64

12
投票

作为一个小小的补充,要获得 DataFrame 列缺失的百分比,结合上面 @Jeff 和 @userS 的答案可以得到:

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

7
投票

下面的方法可以解决问题,并返回每列的空值计数:

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

df.isnull()
返回具有 True / False 值的数据框
sum(axis=0)
对一列的所有行的值求和


3
投票

这不是一个完整的摘要,但它可以让您快速了解列级数据

def getPctMissing(series):
    num = series.isnull().sum()
    den = series.count()
    return 100*(num/den)

2
投票

如果你想查看每列的非空摘要,只需使用

df.info(null_counts=True)
:

示例1:

df = pd.DataFrame(np.random.randn(10,5), columns=list('abcde'))
df.iloc[:4,0] = np.nan
df.iloc[:3,1] = np.nan
df.iloc[:2,2] = np.nan
df.iloc[:1,3] = np.nan

df.info(null_counts=True)

输出:


<class 'pandas.core.frame.DataFrame'>
RangeIndex: 10 entries, 0 to 9
Data columns (total 5 columns):
 #   Column  Non-Null Count  Dtype  
---  ------  --------------  -----  
 0   a       6 non-null      float64
 1   b       7 non-null      float64
 2   c       8 non-null      float64
 3   d       9 non-null      float64
 4   e       10 non-null     float64
dtypes: float64(5)
memory usage: 528.0 bytes

另外,如果你想自定义结果,比如添加nan_rate,我写了一个方法


def describe_nan(df):
    return pd.DataFrame([(i, df[df[i].isna()].shape[0],df[df[i].isna()].shape[0]/df.shape[0]) for i in df.columns], columns=['column', 'nan_counts', 'nan_rate'])

describe_nan(df)

>>> column  nan_counts  nan_rate
0   a   4   0.4
1   b   3   0.3
2   c   2   0.2
3   d   1   0.1
4   e   0   0.0


0
投票

如果您不关心哪些列有 Nan,而只想检查整体情况,只需添加第二个 .sum() 即可获取单个值。

result = df.isnull().sum().sum()
result > 0

一个 Series 只需要一个 .sum(),而一个 Panel() 则需要三个


0
投票

我必须处理大量大型数据集才能获取 NaN 信息(每列的计数和部分),并且时间安排是一个问题。因此,我计时了各种方法来获取单独数据框中每列 NaN 的汇总计数,其中列名称、NaN 计数和 NaN 部分作为列:

# create random dataframe
dfa = pd.DataFrame(np.random.randn(100000,300))
# add 30% random NaNs
dfa = dfa.mask(np.random.random(dfa.shape) < 0.3)

仅使用 pandas 方法:

%%timeit
nans_dfa = dfa.isna().sum().rename_axis('Columns').reset_index(name='Counts')
nans_dfa["NaNportions"] = nans_dfa["Counts"] / dfa.shape[0]

# Output:
# 10 loops, best of 5: 57.8 ms per loop

使用列表理解,基于来自@Mithril的精细答案

%%timeit
nan_dfa_loop2 = pd.DataFrame([(col, dfa[dfa[col].isna()].shape[0], dfa[dfa[col].isna()].shape[0]/dfa.shape[0]) for col in dfa.columns], columns=('Columns', 'Counts', 'NaNportions'))

# Output:
# 1 loop, best of 5: 13.9 s per loop

使用列表理解和第二个for循环来存储方法调用的结果,以减少对这些方法的调用:

%%timeit
nan_dfa_loop1 = pd.DataFrame([(col, n, n/dfa.shape[0]) for col in dfa.columns for n in (dfa[col].isna().sum(),) if n], columns=('Columns', 'Counts', 'NaNportions'))

# Output:
# 1 loop, best of 5: 373 ms per loop

以上所有内容都会产生相同的数据框:

    Columns Counts  NaNportions
0   0   29902   0.29902
1   1   30101   0.30101
2   2   30008   0.30008
3   3   30194   0.30194
4   4   29856   0.29856
... ... ... ...
295 295 29823   0.29823
296 296 29818   0.29818
297 297 29979   0.29979
298 298 30050   0.30050
299 299 30192   0.30192

(“列”对于这个测试数据帧来说是多余的。它只是用作占位符,在现实生活中的数据集中,它可能代表初始数据帧中属性的名称。)


0
投票

更精确一点:

missed_values = df.isnull()

for col in missed_values.columns.values.tolist():

   if True in missed_values[col].values:
       print(missed_values[col].name, missed_values[col].value_counts())

0
投票

这是让您的生活变得轻松的代码

import sidetable

df.stb.missing()

看看这个:https://github.com/chris1610/sidetable


0
投票

如果您想检查哪些列有缺失值,您可以:

mydata.isna().any()

如果该列有任何缺失值,它将打印 True

col1  False
col2  False
col3  True

如果您想要缺失值的计数,则可以输入:

mydata.isna().sum()

这将打印每列缺失值的行数

col1  0
col2  0
col3  5

-1
投票

我建议使用missingno包(https://github.com/ResidentMario/missingno),它可以让你快速、轻松地可视化pandas数据框中丢失的数据。我最喜欢的可视化是条形图,但他们还有其他的。

import missingno as msno
import pandas as pd

df = pd.read_csv('some_data.csv')

msno.bar(df.sample(1000))
© www.soinside.com 2019 - 2024. All rights reserved.