Python Pandas groupby:如何进行依赖于其他列的条件聚合

问题描述 投票:1回答:1

我想将Panda的groupby与多个聚合函数一起使用,但还要在每个聚合中包含条件语句。想象一下以该数据为例:

df = pd.DataFrame({
    'id': ['a', 'a', 'a', 'b', 'b'],
    'type': ['in_scope', 'in_scope', 'exclude', 'in_scope', 'exclude'],
    'value': [5, 5, 99, 20, 99]
})
INPUT DATA:
| id | in_scope | value |
|----|----------|-------|
| a  | True     | 5     |
| a  | True     | 5     |
| a  | False    | 99    |
| b  | True     | 20    |
| b  | False    | 99    |

而且我想像这样做一个熊猫分组:

df.groupby('id').agg(
    num_records=('id', 'size'),
    sum_value=('value', np.sum)
)
OUTPUT OF SIMPLE GROUPBY:
| id | num_records | sum_value |
|----|-------------|-----------|
| a  | 3           | 109       |
| b  | 2           | 119       |

但是,我想根据条件进行总和,即仅应使用在True列中定义为in_scope的“ in_scope”记录。注意,第一次聚合仍应使用整个表。简而言之,这是所需的输出:

DESIRED OUTPUT OF GROUPBY:
| id | num_records | sum_value_in_scope |
|----|-------------|--------------------|
| a  | 3           | 10                 |
| b  | 2           | 20                 |

我正在考虑将两个参数传递给lambda函数,但是我没有成功。当然,可以通过对已过滤和未过滤的数据执行两个单独的groupby并将其组合在一起来解决。但是我希望有一种更短,更优雅的方法。

python filter conditional-statements aggregate pandas-groupby
1个回答
0
投票

很遗憾,您不能使用聚合来完成此操作,但是可以通过应用和自定义功能一步来完成:

def f(x):
    d = {}
    d['num_records'] = len(x)
    d['sum_value_in_scope'] = x[x.in_scope].value.sum()
    return pd.Series(d, index=['num_records', 'sum_value_in_scope'])

df.groupby('id').apply(f)

由于列df.in_scope已经为布尔值,因此可以将其直接用作掩码来过滤求和的值。如果您正在使用的列不是布尔值,则最好使用df.query('<your query here>')来获取数据的子集(在幕后进行了优化,使其比大多数其他方法都快)。

© www.soinside.com 2019 - 2024. All rights reserved.