本文介绍如何对 dataframe 中两个平行的列表型列(如类别与对应分值)进行元素级对齐,通过 explode 与 pivot_table 实现按类别汇总求和、正负计数等多维度统计。
本文介绍如何对 dataframe 中两个平行的列表型列(如类别与对应分值)进行元素级对齐,通过 explode 与 pivot_table 实现按类别汇总求和、正负计数等多维度统计。
在实际数据处理中,常遇到将“类别列表”与“数值列表”成对存储于 DataFrame 列中的场景(例如每条记录代表一个实体,其拥有多组带标签的指标)。此时,简单 groupby 无法直接生效——因为列表未展开,且两列需严格按位置配对。核心解决思路是:先同步展开(explode),再按类别透视聚合。
以下为完整实现流程:
- 同步展开双列:使用 df.explode(["cat", "pts"]) 确保每个类别-分值对作为独立行存在,且索引保留原始记录归属关系;
- 定义聚合函数:除内置 'sum' 外,自定义 pos 和 neg 函数分别统计正值与负值个数;
- 多级聚合透视:调用 pivot_table(..., aggfunc=["sum", pos, neg]),生成 MultiIndex 列;
- 扁平化列名:将 ('sum', 'speed') 类列重命名为 'speed_sum',('pos', 'health') → 'health_pos';
- 合并回原表:用 pd.concat([df, tmp], axis=1) 拼接结果。
import pandas as pd
# 构造示例数据
cat = [
['speed', 'health', 'strength', 'health'],
['strength', 'speed', 'speed'],
['strength', 'speed', 'health', 'speed']
]
pts = [
[1, 2, 1.5, -1],
[2, -1.5, 1.5],
[-1, 2, 0, 1.5]
]
df = pd.DataFrame({"cat": cat, "pts": pts})
# 自定义聚合函数
def pos(vals): return (vals > 0).sum()
def neg(vals): return (vals <p>✅ <strong>关键注意事项</strong>: </p>
- explode 必须同时指定 ["cat", "pts"] —— 若分开 explode 会导致索引错位、配对失准;
- pivot_table 中 index=tmp.index 是保留原始行关系的核心,不可省略;
- 对于某类别在某行中完全缺失的情况(如第1行无 health),结果自动填充 NaN,符合预期;
- 若需统一填充 0 替代 NaN,可在最后添加 .fillna(0),但需注意语义(缺失 vs 零值);
- 性能提示:该方法适用于中等规模数据(万级记录内);超大规模时建议改用 itertools.chain + defaultdict 手动聚合以避免内存膨胀。
该方案兼具可读性与扩展性——只需增删 aggfunc 中的函数,即可轻松支持均值、标准差、最大值等任意统计维度,是处理“平行列表列”关联分析的标准范式。










