python - Pandas 对所有列使用 groupby 计数 NA
问题描述
这个问题显示了如何计算特定列 C 的数据框中的 NA。如何计算所有列(不是 groupby 列)的 NA?
这是一些不起作用的测试代码:
#!/usr/bin/env python3
import pandas as pd
import numpy as np
df = pd.DataFrame({'a':[1,1,2,2],
'b':[1,np.nan,2,np.nan],
'c':[1,np.nan,2,3]})
# result = df.groupby('a').isna().sum()
# AttributeError: Cannot access callable attribute 'isna' of 'DataFrameGroupBy' objects, try using the 'apply' method
# result = df.groupby('a').transform('isna').sum()
# AttributeError: Cannot access callable attribute 'isna' of 'DataFrameGroupBy' objects, try using the 'apply' method
result = df.isna().groupby('a').sum()
print(result)
# result:
# b c
# a
# False 2.0 1.0
result = df.groupby('a').apply(lambda _df: df.isna().sum())
print(result)
# result:
# a b c
# a
# 1 0 2 1
# 2 0 2 1
期望的输出:
b c
a
1 1 1
2 1 0
解决方案
最好避免groupby.apply
使用 cythonized 的基本功能,因为这可以更好地适应许多组。这将导致性能大幅提升。在这种情况下,首先检查isnull()
整个DataFrame
then groupby
+ sum
。
df[df.columns.difference(['a'])].isnull().groupby(df.a).sum().astype(int)
# b c
#a
#1 1 1
#2 1 0
为了说明性能增益:
import pandas as pd
import numpy as np
N = 50000
df = pd.DataFrame({'a': [*range(N//2)]*2,
'b': np.random.choice([1, np.nan], N),
'c': np.random.choice([1, np.nan], N)})
%timeit df[df.columns.difference(['a'])].isnull().groupby(df.a).sum().astype(int)
#7.89 ms ± 187 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
%timeit df.groupby('a')[['b', 'c']].apply(lambda x: x.isna().sum())
#9.47 s ± 111 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
推荐阅读
- http-live-streaming - HLS 清单的实际最大长度
- astropy - 关于 Astropy Kuiper 测试中 fpp 的问题
- discord - discord bot 怎么知道你玩游戏多久了?
- python-3.x - 在python中将元组表示为二进制
- javascript - (javascript) 如何在表格 html 上像 classList.toggle 一样隐藏和显示 innerHTML?
- python - 将 ESPN 当前周的 NFL 行刮到 pandas 数据框中
- html - 如何在页面上随机放置背景元素?
- html - 为什么我不能为锚元素设置样式?
- postgresql - 如何使用 SQL 平均数天的每小时值
- php - 在 PHP 中序列化/反序列化布尔数据