如何按日期块计算前一日累计和并生成invest判断标记?
问题:按日期计算前一日累计和并生成invest标记
原始CSV数据
clock_now,competition,market_name,back,lay 2022/08/09,South African Premier Division,Over/Under 0.5 Goals,0.28985,-1.0 2022/08/12,South African Premier Division,Over/Under 0.5 Goals,-1.0,1.28 2022/09/07,South African Premier Division,Over/Under 0.5 Goals,0.37,-1.0 2022/09/07,South African Premier Division,Over/Under 0.5 Goals,0.20,-1.0 2022/10/15,South African Premier Division,Over/Under 0.5 Goals,0.20,1.0 2022/10/15,South African Premier Division,Over/Under 0.5 Goals,0.20,1.0 2022/10/15,South African Premier Division,Over/Under 0.5 Goals,0.20,1.0 2022/11/20,South African Premier Division,Over/Under 0.5 Goals,0.20,1.0
说明:back列与lay列的数据每日午夜(00:00)更新。
原尝试代码
combinations = [['market_name', 'competition']] for cbnt in combinations: df['invest'] = df.groupby(cbnt)['lay'].cumsum().gt(df['lay'])
当前错误结果
clock_now cumulativesum invest 0 2022/08/09 -1.00 False 1 2022/08/12 0.28 False 2 2022/09/07 -0.72 True 3 2022/09/07 -1.72 False 4 2022/10/15 -0.72 False 5 2022/10/15 0.28 False 6 2022/10/15 1.28 True 7 2022/11/20 2.28 True
预期结果
- 截至
2022/08/09的累计和为0,对应False - 截至
2022/08/12的累计和为-1,对应False - 截至
2022/09/07的累计和为+0.28,对应True - 截至
2022/09/07的累计和为+0.28,对应True - 截至
2022/10/15的累计和为-1.72,对应False - 截至
2022/10/15的累计和为-1.72,对应False - 截至
2022/10/15的累计和为-1.72,对应False - 截至
2022/11/20的累计和为+1.28,对应True
需要修改代码实现:按日期计算前一日累计和,并生成对应invest标记。
解决方案
核心思路
- 先按分组条件+日期聚合,计算每日
lay列的总和 - 计算截至前一日的累计和(对每日总和做累加后向前偏移一位,初始值设为0)
- 将前一日累计和匹配回原数据的对应日期行,判断是否大于0生成
invest标记
修改后的代码
import pandas as pd # 读取数据(假设已完成) # df = pd.read_csv("your_data.csv") # 转换日期格式,确保分组准确性 df['clock_now'] = pd.to_datetime(df['clock_now']) combinations = [['market_name', 'competition']] for cbnt in combinations: # 1. 按分组条件+日期,计算每日lay的总和 daily_lay_sum = df.groupby(cbnt + ['clock_now'])['lay'].sum().reset_index() # 2. 按分组条件计算截至前一日的累计和,第一天累计值为0 daily_lay_sum['prev_cum_sum'] = daily_lay_sum.groupby(cbnt)['lay'].cumsum().shift(1).fillna(0) # 3. 将前一日累计和合并回原数据表 df = df.merge(daily_lay_sum[cbnt + ['clock_now', 'prev_cum_sum']], on=cbnt + ['clock_now'], how='left') # 4. 判断前一日累计和是否大于0,生成invest标记 df['invest'] = df['prev_cum_sum'] > 0 # 查看结果(可选) print(df[['clock_now', 'prev_cum_sum', 'invest']])
代码解释
- 日期转换:把
clock_now转为日期类型,避免字符串格式导致的分组错误 - 每日总和计算:同日期多行的
lay值先求和,确保累计和按日期维度正确计算 - 前一日累计:用
shift(1)将累加结果向后偏移,得到每一行日期对应的前一日累计值,fillna(0)处理第一天无历史数据的情况 - 匹配与标记:将计算好的累计值合并回原数据,直接通过判断生成
invest列
验证结果
运行后得到的结果完全符合预期:
| clock_now | prev_cum_sum | invest |
|---|---|---|
| 2022-08-09 | 0.00 | False |
| 2022-08-12 | -1.00 | False |
| 2022-09-07 | 0.28 | True |
| 2022-09-07 | 0.28 | True |
| 2022-10-15 | -1.72 | False |
| 2022-10-15 | -1.72 | False |
| 2022-10-15 | -1.72 | False |
| 2022-11-20 | 1.28 | True |
内容的提问来源于stack exchange,提问作者Digital Farmer
相关产品推荐
相关产品推荐

