根据使用多列的条件聚合Pandas DataFrame?

时间:2016-09-08 14:14:41

标签: python pandas dataframe

import pandas as pd

data = {
    "K": ["A", "A", "B", "B", "B"],
    "LABEL": ["X123", "X123", "X21", "L31", "L31"],
    "VALUE": [1, 3, 1, 2, 5.0]
}

df = pd.DataFrame.from_dict(data)

output = """
   K LABEL  VALUE
0  A   X12    1.0
1  A   X12    3.0
2  B   X21    1.0
3  B   L31    2.0
4  B   L31    5.0
"""

转换步骤

对于每个组(按K分组),找到下面定义的FINAL_VALUE。

LABEL是两种类型X__和L __

# if LABEL is X___ then FINAL_VALUE = sum(VALUE)
# if LABEL is L___ then FINAL_VALUE = count(VALUE)
# else FINAL_VALUE = 0

转型结果

expected_output = """
K  LABEL  FINAL_VALUE
A    X12            4
B    X21            1
B    L31            2
"""

如何使用Pandas实现这一目标?

EDIT1 :部分正常工作

In [17]: df.groupby(["K", "LABEL"]).agg({"VALUE": {"VALUE_SUM": "sum", "VALUE_COUNT": "count"}})
Out[17]: 
              VALUE          
        VALUE_COUNT VALUE_SUM
K LABEL                      
A X12             2       4.0
B L31             2       7.0
  X21             1       1.0

EDIT2 :使用reset_index()填充数据框

In [18]: df2 = df.groupby(["K", "LABEL"]).agg({"VALUE": {"VALUE_SUM": "sum", "VALUE_COUNT": "count"}})

In [21]: df2.reset_index()
Out[21]: 
   K LABEL       VALUE          
           VALUE_COUNT VALUE_SUM
0  A   X12           2       4.0
1  B   L31           2       7.0
2  B   X21           1       1.0

EDIT3:使用df.apply()

的最终解决方案
In [59]: df3 = df2.reset_index()

In [60]: df3["FINAL_VALUE"] = df3.apply(lambda x: x["VALUE"]["VALUE_SUM"] if x["LABEL"].str.startswith("X").any() else x["VALUE"]["VALUE_COUNT"] , axis=1)

In [61]: df3[["K", "LABEL", "FINAL_VALUE"]]
Out[61]: 
   K LABEL FINAL_VALUE

0  A   X12         4.0
1  B   L31         2.0
2  B   X21         1.0

2 个答案:

答案 0 :(得分:2)

您可以像以前一样使用DFGroupby.agg,然后编写一个通用函数,在str.startswith的帮助下计算必要的要求,并返回所需的框架,如下所示:

def compute_multiple_condition(row):
    if row['LABEL'].startswith('X'):
        return row['sum']
    elif row['LABEL'].startswith('L'):
          return row['count']
    else:
        return 0

df = df.groupby(['K','LABEL'])['VALUE'].agg({'sum': 'sum', 'count': 'count'}).reset_index()
df['FINAL_VALUE'] = df.apply(compute_multiple_condition, axis=1).astype(int)
df = df[['K', 'LABEL', 'FINAL_VALUE']]
df

   K LABEL  FINAL_VALUE
0  A   X12            4
1  B   L31            2
2  B   X21            1

答案 1 :(得分:0)

您可以尝试数据框链:

result = (df.groupby(['K', 'LABEL'])
            .apply(lambda frame: frame.VALUE.sum() 
                                if frame.LABEL.iloc[0].startswith("X") else len(frame))
            .to_frame()
            .rename({'0': 'FINAL_VALUE'})
         )