0

0

如何在Pandas中按多列分组计算并广播结果到原始DataFrame的每一行

碧海醫心

碧海醫心

发布时间:2025-12-31 13:26:22

|

754人浏览过

|

来源于php中文网

原创

如何在Pandas中按多列分组计算并广播结果到原始DataFrame的每一行

本文详解如何使用pandas对dataframe按多个列(如deal、commodity、startdate)分组,执行自定义聚合计算(如fprice公式),并将标量结果准确广播回原始数据的每一行,避免索引错位问题。

在Pandas中,对多列分组后进行聚合计算并“广播”结果到原始每行,是常见但易出错的操作。许多初学者尝试直接用 groupby(...).apply(...) 的返回值赋值给新列(如 df['fprice'] = ...),却因apply返回的是缩减后的Series(索引为分组键),而原始DataFrame索引未对齐,导致赋值错位(如示例中J2被错误赋予1.25)、部分行缺失或NaN——这正是原问题的核心症结。

✅ 正确做法是:分离计算与对齐两个步骤——先独立计算每组的聚合值,生成一个含分组键和结果的中间表;再通过merge(或map)将其安全、精确地回填至原始DataFrame。

以下为完整、可复现的解决方案:

import pandas as pd

# 示例数据(注意列名大小写需与实际一致)
df = pd.DataFrame({
    'ID': ['J1', 'J2', 'J3', 'J4'],
    'Deal': ['Sell', 'Sell', 'Buy', 'Buy'],
    'Party': ['J', 'J', 'J', 'J'],
    'Commodity': ['(stock1, stock2)'] * 4,
    'startdate': ['01Jan23'] * 4,
    'enddate': ['01Feb23'] * 4,
    'fixedpricestrike': [10.0, 10.0, 5.0, 5.0],
    'quantity': [10, 10, 10, 5],
    'mtmvalue': [100.0, 100.0, 50.0, 25.0]
})

# ✅ 步骤1:分组聚合,计算每组的 fprice(公式:-(∑mtm - ∑(strike×qty)) / ∑qty)
fprice_series = df.groupby(['startdate', 'Commodity', 'Deal']).apply(
    lambda g: -(g['mtmvalue'].sum() - (g['fixedpricestrike'] * g['quantity']).sum()) / g['quantity'].sum()
)

# 将结果转为DataFrame,重命名列为'fprice'
grouped_fprice = fprice_series.reset_index(name='fprice')

# ✅ 步骤2:左连接回原始DataFrame(关键!确保每行按分组键精准匹配)
df = pd.merge(df, grouped_fprice, on=['startdate', 'Commodity', 'Deal'], how='left')

print(df)

输出结果将严格符合预期:

Endel.io
Endel.io

Endel是一款可以创造个性化舒缓声音的应用程序,可帮助您集中注意力、放松身心和入睡。

下载
   ID  Deal Party         Commodity startdate  enddate  fixedpricestrike  quantity  mtmvalue  fprice
0  J1  Sell     J  (stock1, stock2)   01Jan23  01Feb23              10.0        10.0     100.0     0.0
1  J2  Sell     J  (stock1, stock2)   01Jan23  01Feb23              10.0        10.0     100.0     0.0
2  J3   Buy     J  (stock1, stock2)   01Jan23  01Feb23               5.0        10.0      50.0    1.25
3  J4   Buy     J  (stock1, stock2)   01Jan23  01Feb23               5.0         5.0      25.0    1.25

? 关键注意事项:

  • 列名一致性:merge的on参数必须与groupby键完全一致(包括大小写、空格),否则合并失败或产生NaN。
  • 性能考量:对超大数据集,merge比map稍慢但更鲁棒;若分组键唯一且为字符串/数值,也可用df['fprice'] = df.set_index(['startdate','Commodity','Deal']).index.map(fprice_series)。
  • 公式验证:本例中Buy组计算为 -(50+25 - (5×10 + 5×5)) / (10+5) = -(75 - 75)/15 = 0?但原文示例为1.25,说明实际业务逻辑可能不同,请务必根据真实公式调整lambda内计算逻辑。
  • 缺失值处理:how='left'确保原始行不丢失;若某组在聚合中无结果(如全NaN),对应fprice将为NaN,建议后续用df['fprice'].fillna(0)处理。

掌握“先聚合、再对齐”的范式,即可稳健解决任意多列分组广播问题,远离索引陷阱。

相关专题

更多
Python 时间序列分析与预测
Python 时间序列分析与预测

本专题专注讲解 Python 在时间序列数据处理与预测建模中的实战技巧,涵盖时间索引处理、周期性与趋势分解、平稳性检测、ARIMA/SARIMA 模型构建、预测误差评估,以及基于实际业务场景的时间序列项目实操,帮助学习者掌握从数据预处理到模型预测的完整时序分析能力。

49

2025.12.04

js 字符串转数组
js 字符串转数组

js字符串转数组的方法:1、使用“split()”方法;2、使用“Array.from()”方法;3、使用for循环遍历;4、使用“Array.split()”方法。本专题为大家提供js字符串转数组的相关的文章、下载、课程内容,供大家免费下载体验。

248

2023.08.03

js截取字符串的方法
js截取字符串的方法

js截取字符串的方法有substring()方法、substr()方法、slice()方法、split()方法和slice()方法。本专题为大家提供字符串相关的文章、下载、课程内容,供大家免费下载体验。

205

2023.09.04

java基础知识汇总
java基础知识汇总

java基础知识有Java的历史和特点、Java的开发环境、Java的基本数据类型、变量和常量、运算符和表达式、控制语句、数组和字符串等等知识点。想要知道更多关于java基础知识的朋友,请阅读本专题下面的的有关文章,欢迎大家来php中文网学习。

1435

2023.10.24

字符串介绍
字符串介绍

字符串是一种数据类型,它可以是任何文本,包括字母、数字、符号等。字符串可以由不同的字符组成,例如空格、标点符号、数字等。在编程中,字符串通常用引号括起来,如单引号、双引号或反引号。想了解更多字符串的相关内容,可以阅读本专题下面的文章。

609

2023.11.24

java读取文件转成字符串的方法
java读取文件转成字符串的方法

Java8引入了新的文件I/O API,使用java.nio.file.Files类读取文件内容更加方便。对于较旧版本的Java,可以使用java.io.FileReader和java.io.BufferedReader来读取文件。在这些方法中,你需要将文件路径替换为你的实际文件路径,并且可能需要处理可能的IOException异常。想了解更多java的相关内容,可以阅读本专题下面的文章。

547

2024.03.22

php中定义字符串的方式
php中定义字符串的方式

php中定义字符串的方式:单引号;双引号;heredoc语法等等。想了解更多字符串的相关内容,可以阅读本专题下面的文章。

539

2024.04.29

go语言字符串相关教程
go语言字符串相关教程

本专题整合了go语言字符串相关教程,阅读专题下面的文章了解更多详细内容。

157

2025.07.29

vlookup函数使用大全
vlookup函数使用大全

本专题整合了vlookup函数相关 教程,阅读专题下面的文章了解更多详细内容。

28

2025.12.30

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
CSS3 教程
CSS3 教程

共18课时 | 4.1万人学习

PostgreSQL 教程
PostgreSQL 教程

共48课时 | 6.3万人学习

Django 教程
Django 教程

共28课时 | 2.6万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号