【问题标题】:Vectorizing the aggregation operation on different columns of a Pandas dataframe向量化 Pandas 数据帧不同列上的聚合操作
【发布时间】:2023-01-12 19:25:10
【问题描述】:

我有一个 Pandas 数据框,主要包含布尔列。一个小例子是:

import pandas as pd

df = pd.DataFrame({"A": [1, 2, 3, 1, 2, 3],
                   "B": ['a', 'b', 'c', 'a', 'b', 'c'],
                   "f1": [True, True, True, True, True, False],
                   "f2": [True, True, True, True, False, True],
                   "f3": [True, True, True, False, True, True],
                   "f4": [True, True, False, True, True, True],
                   "f5": [True, False, True, True, True, True],
                   "target1": [True, False, True, True, False, True],
                   "target2": [False, True, True, False, True, False]})

df

输出:

    A   B   f1      f2      f3      f4      f5    target1  target2
0   1   a   True    True    True    True    True    True    False
1   2   b   True    True    True    True    False   False   True
2   3   c   True    True    True    False   True    True    True
3   1   a   True    True    False   True    True    True    False
4   2   b   True    False   True    True    True    False   True
5   3   c   False   True    True    True    True    True    False

对于每个 f 列的每个 True 和 False 类以及("A", "B") 列中的所有组,我想对 target1target2 列进行求和。在 f 列上使用循环,我们有:

for col in ["f1", "f2", "f3", "f4", "f5"]:
    print(col, "\n", 
          df[df[col]].groupby(["A", "B"]).agg({"target1": "sum", "target2": "sum"}), "\n",
          df[~df[col]].groupby(["A", "B"]).agg({"target1": "sum", "target2": "sum"}))

现在,我需要在没有 for 循环的情况下完成它;我的意思是对 f 列进行 vecotization 以减少计算时间(计算时间应该几乎等于为一个 f 列执行此操作所需的时间)。

【问题讨论】:

  • 请添加预期的输出数据框

标签: python pandas group-by


【解决方案1】:

利用:

df = df.melt(['A','B','target1','target2'])

df1 = df.groupby(["A", "B","variable","value"]).agg({"target1": "sum", "target2": "sum"})
print (df1)
                    target1  target2
A B variable value                  
1 a f1       True         2        0
    f2       True         2        0
    f3       False        1        0
             True         1        0
    f4       True         2        0
    f5       True         2        0
2 b f1       True         0        2
    f2       False        0        1
             True         0        1
    f3       True         0        2
    f4       True         0        2
    f5       False        0        1
             True         0        1
3 c f1       False        1        0
             True         1        1
    f2       True         2        1
    f3       True         2        1
    f4       False        1        1
             True         1        0
    f5       True         2        1

然后可以通过以下方式进行选择:

print (df1.query("variable=='f1' and value==True").droplevel([-1,-2]))
     target1  target2
A B                  
1 a        2        0
2 b        0        2
3 c        1        1

或者:

idx = pd.IndexSlice
print (df1.loc[idx[:, :, 'f1', True],:].droplevel([-1,-2]))
     target1  target2
A B                  
1 a        2        0
2 b        0        2
3 c        1        1

【讨论】:

    猜你喜欢
    • 2016-04-29
    • 1970-01-01
    • 2019-08-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多