You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

按站点分组并条件聚合数据的Python实现问题

问题描述

本人是Python新手,正在处理一份大型案例级数据集,数据集结构如下:

Site          Type          Value
A              Red            10
A              Blue           15
B              Red            35
B              Yellow          5
C              Blue           45
C              Red            25

需要通过Python自动化完成按站点分组的聚合操作,期望输出格式如下:

Site         RedType    BlueType   YellowType    Value0-20    Value20-40    Value40+
A               1           1          0              2            0           0
B               1           0          1              1            1           0
C               1           1          0              0            1           1

目前尝试通过自定义聚合函数结合groupby实现,代码如下:

def my_agg(data):
    names = {
        'RedType': data[data['Type']=="Red"]['Id'].count(),
        'BlueType': data[data['Type']=="Blue"]['Id'].count(),
        'YellowType':data[data['Type']=="Yellow"]['Id'].count(),
        'Value0-20': data[data['Value']>=0]['Id'].count() and data[data['Value']<=20]['Id'].count()
        # etc........
    }
    return pd.Series(names)

df = data.groupby('Site').apply(my_agg)

已知上述代码中Value区间计数的and运算符逻辑无效,其余部分可正常运行。请问如何通过该方式实现Value区间的条件计数?此外是否有更优的实现方案?

解决方案

一、修复自定义聚合函数的区间计数逻辑

你代码里用and实现多条件筛选是错误的——数字之间的and会做布尔判断,无法实现交集筛选。正确做法是把两个条件合并到同一个布尔索引中,同时注意原代码里的Id列在数据集里不存在,要替换成现有列(比如Type或Value)计数:

import pandas as pd

def my_agg(data):
    names = {
        'RedType': data[data['Type'] == "Red"]['Type'].count(),
        'BlueType': data[data['Type'] == "Blue"]['Type'].count(),
        'YellowType': data[data['Type'] == "Yellow"]['Type'].count(),
        'Value0-20': data[(data['Value'] >= 0) & (data['Value'] <= 20)]['Value'].count(),
        'Value20-40': data[(data['Value'] > 20) & (data['Value'] <= 40)]['Value'].count(),
        'Value40+': data[data['Value'] > 40]['Value'].count()
    }
    return pd.Series(names)

# 假设data是你的数据集DataFrame
df = data.groupby('Site').apply(my_agg).reset_index()

关键注意点:

  • 多条件筛选必须用&运算符,且每个条件要加括号避免优先级问题
  • 计数列要选用数据集中存在的列,否则会触发KeyError

二、更优实现方案:透视表+区间划分

处理大型数据集时,自定义apply函数效率较低,推荐用pd.pivot_table结合pd.cut的组合方案,代码更简洁且运行速度更快:

步骤1:统计各站点的Type类型数量

# 生成各Site下不同Type的计数,空值填充为0
type_pivot = pd.pivot_table(data, index='Site', columns='Type', aggfunc='size', fill_value=0)
# 重命名列名匹配期望输出
type_pivot = type_pivot.rename(columns={'Red': 'RedType', 'Blue': 'BlueType', 'Yellow': 'YellowType'})

步骤2:统计各站点的Value区间数量

# 定义区间边界和对应标签
bins = [-float('inf'), 20, 40, float('inf')]
labels = ['Value0-20', 'Value20-40', 'Value40+']
# 给每条数据打区间标签
data['ValueInterval'] = pd.cut(data['Value'], bins=bins, labels=labels)
# 透视统计各Site下的区间数量
value_pivot = pd.pivot_table(data, index='Site', columns='ValueInterval', aggfunc='size', fill_value=0)

步骤3:合并结果

# 按Site合并两个透视表,得到最终格式
final_df = pd.concat([type_pivot, value_pivot], axis=1).reset_index()

内容的提问来源于stack exchange,提问作者BMcBee

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.06 14:03:12