给出以下df
id val1 val2 val3
0 1 A A B
1 1 A B B
2 1 B C NaN
3 1 NaN B D
4 2 A D NaN
我想对所有列的每个id
组中的值计数求和;但是,我只需计算出现在同一行上的值一次,因此预期输出为:
id
1 B 4
A 2
C 1
D 1
2 A 1
D 1
我可以用
完成这项工作import pandas as pd
df.set_index('id').apply(lambda x: list(set(x)), axis=1).apply(pd.Series).stack().groupby(level=0).value_counts()
但apply(...axis=1)
(可能还有apply(pd.Series)
)确实会导致大型DataFrames
的性能下降。由于我的列数较少,我想我可以检查所有成对重复,用np.NaN
替换一个,然后只使用df.set_index('id').stack().groupby(level=0).value_counts()
但这似乎不是正确的方法列数变大。
有关更快的解决方法的任何想法吗?
答案 0 :(得分:1)
以下是从数据框中删除行重复项的缺失步骤:
nodups = df.stack().reset_index(level=0).drop_duplicates()
nodups = nodups.set_index(['level_0', nodups.index]).unstack()
nodups.columns = nodups.columns.levels[1]
# id val1 val2 val3
#level_0
#0 1 A None B
#1 1 A B None
#2 1 B C None
#3 1 None B D
#4 2 A D None
现在您可以关注:
nodups.set_index('id').stack().groupby(level=0).value_counts()
也许您可以进一步优化代码。
答案 1 :(得分:1)
我正在使用get_dummies
s=df.set_index('id',append=True).stack().str.get_dummies().sum(level=[0,1]).gt(0).sum(level=1).stack().astype(int)
s[s.gt(0)]
Out[234]:
id
1 A 2
B 4
C 1
D 1
2 A 1
D 1
dtype: int32