是否有更快的方法来计算多列中的值,不包括同一行上的重复值?

时间:2018-05-22 21:50:25

标签: python pandas

给出以下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()但这似乎不是正确的方法列数变大。

有关更快的解决方法的任何想法吗?

2 个答案:

答案 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