This question显示了如何为特定列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
答案 0 :(得分:2)
将apply
与isna
和sum
一起使用。另外,我们选择正确的列,因此不会出现不必要的a
列:
注意:apply
可能很慢,建议使用一种矢量化解决方案,请参阅WenYoBen
,Anky
或{{3 }}
df.groupby('a')[['b', 'c']].apply(lambda x: x.isna().sum())
输出
b c
a
1 1 1
2 1 0
答案 1 :(得分:2)
始终最好避免使用groupby.apply
来支持cythonized的基本功能,因为这在许多组中可以更好地扩展。这将导致性能大大提高。在这种情况下,请先在整个isnull()
上检查DataFrame
,然后再检查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)
答案 2 :(得分:2)
另一种方法是在set_index()
上使用a
并在索引和总和上使用groupby:
df.set_index('a').isna().groupby(level=0).sum()*1
或者:
df.set_index('a').isna().groupby(level=0).sum().astype(int)
或者没有@byWenYoBen的集体照:
df.set_index('a').isna().sum(level=0).astype(int)
b c
a
1 1 1
2 1 0
答案 3 :(得分:1)
我先做count
,然后再写成value_counts
,这是我没有使用apply
的原因,因为它通常表现不佳
df.groupby('a')[['b','c']].count().rsub(df.a.value_counts(dropna=False),axis=0)
Out[78]:
b c
1 1 1
2 1 0
替代
df.isna().drop('a',1).astype(int).groupby(df['a']).sum()
Out[83]:
b c
a
1 1 1
2 1 0
答案 4 :(得分:1)
您的问题有答案(您将_df
的错误键入为df
):
result = df.groupby('a')['b', 'c'].apply(lambda _df: _df.isna().sum())
result
b c
a
1 1 1
2 1 0
答案 5 :(得分:1)
使用drop
后,您需要apply
列。
df.groupby('a').apply(lambda x: x.isna().sum()).drop('a',1)
输出:
b c
a
1 1 1
2 1 0
答案 6 :(得分:1)
另一项肮脏的工作:
full_name
输出:
df.set_index('a').isna().astype(int).groupby(level=0).sum()
答案 7 :(得分:0)
您可以编写自己的聚合函数,如下所示:
df.groupby('a').agg(lambda x: x.isna().sum())
结果
b c
a
1 1.0 1.0
2 1.0 0.0