如何用Pandas计算IPO后公司逐期累积收益(BHARs)?求替代方案
计算IPO后公司每日收益的累积乘积(按公司分组)
问题背景
我有一个面板结构的Pandas DataFrame,包含约300家公司IPO后的每日收益数据:
day_diff:IPO已过天数return_1:当日单日报酬率(已加1处理)company_tic:公司代码
目标是针对每个company_tic,计算从day0到每个day_diff的return_1累积乘积(例如day0到day1、day0到day2……直至day730)。之前尝试df.groupby(['company_tic', 'day_diff'])['return_1'].expanding().prod()未成功,求替代实现方法。
DataFrame结构示例:
Index day_diff company_tic return_1 0 0 xyz 1.8914 1 1 xyz 1.0542 2 2 xyz 1.0016 3 0 abc 1.4398 4 1 abc 1.1023 5 2 abc 1.0233 ... ... ... ...
解决方案
方法1:分组后直接用cumprod()(最简洁高效)
之前的错误在于把day_diff也纳入了分组条件,导致每个分组仅对应单公司单日数据,无法完成累积计算。正确的做法是仅按company_tic分组,再对return_1使用cumprod()(前提是每个公司的day_diff按升序排列):
# 先确保数据按公司和IPO天数升序排列(若原始数据无序) df = df.sort_values(['company_tic', 'day_diff']) # 新增累积乘积列 df['cumulative_return'] = df.groupby('company_tic')['return_1'].cumprod()
方法2:使用expanding().prod()的正确写法
如果坚持要用expanding,需仅按company_tic分组,再通过reset_index对齐结果:
df = df.sort_values(['company_tic', 'day_diff']) df['cumulative_return'] = df.groupby('company_tic')['return_1'].expanding().prod().reset_index(level=0, drop=True)
方法3:结合transform实现
通过transform可以将分组内的累积计算结果映射回原DataFrame:
df = df.sort_values(['company_tic', 'day_diff']) df['cumulative_return'] = df.groupby('company_tic')['return_1'].transform(lambda x: x.cumprod())
注意事项
- 必须保证每个公司的
day_diff从0开始连续递增,若存在天数缺失或顺序混乱,需先完成排序或补全操作,否则累积结果会出错。 return_1已做加1处理,因此累积乘积直接代表从IPO日到当日的总收益倍数,无需额外转换。
内容的提问来源于stack exchange,提问作者Marie-Pier St-Vincent
相关产品推荐
相关产品推荐

