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

Posted

技术标签:

【中文标题】如何按“熊猫”中的列获取缺失/NaN 数据的汇总计数?【英文标题】:How do I get a summary count of missing/NaN data by column in 'pandas'? 【发布时间】:2014-04-11 00:56:36 【问题描述】:

R中,我可以使用summary 命令快速查看缺失数据的计数,但等效的pandas DataFrame 方法describe 不会报告这些值。

我知道我可以做类似的事情

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

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

【问题讨论】:

行的类似问题:Python/Pandas: counting the number of missing/NaN in each row 【参考方案1】:

describeinfo 都报告非缺失值的计数。

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

【讨论】:

【参考方案2】:

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

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

【讨论】:

【参考方案3】:

下面的方法可以解决问题,并且会为每一列返回空值:

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

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

【讨论】:

【参考方案4】:

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

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

【讨论】:

【参考方案5】:

如果您想查看每列的非空摘要,只需使用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

【讨论】:

【参考方案6】:

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

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

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

【讨论】:

【参考方案7】:

我必须处理大量大型数据集才能获取 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 的精细answer:

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

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

【讨论】:

以上是关于如何按“熊猫”中的列获取缺失/NaN 数据的汇总计数?的主要内容,如果未能解决你的问题,请参考以下文章

如何在熊猫数据框列中获取 NaN 观察的频率 [重复]

如何合并/组合熊猫中的列?

熊猫:在每组中按平均值填充缺失值

熊猫:在每组中按平均值填充缺失值

用之前的非缺失值填充缺失的 pandas 数据,按 key 分组

如何从熊猫中的前一行复制缺失的列值[重复]