如何基于累计天数差实现Pandas DataFrame的最小7天块分组?
按dif累加和分组(最小7天块)的简洁实现
嘿,我完全get到你的需求了——要把DataFrame按dif列的累加和来分组,每组至少凑够7天,最后一组哪怕总和超过7也得全部包含进去。之前用自定义函数搞乱了?别担心,有两个简单又可靠的办法,看你偏好哪种:
方法一:直观循环法(可读性拉满)
这个方法逻辑非常直白,完全跟着你的需求走,不容易出错,适合大多数场景:
import pandas as pd # 加载示例数据(替换成你的真实数据即可) data = { 'date': ['2020-09-18', '2020-09-19', '2020-09-22', '2020-09-23', '2020-09-24', '2020-09-25', '2020-09-26', '2020-09-28', '2020-10-05'], 'groc': [7.94, 13.43, 14.14, 3.07, 7.79, 9.17, 10.44, 3.13, 20.56], 'day': ['Friday', 'Saturday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Monday', 'Monday'], 'dif': [1.0, 1.0, 3.0, 1.0, 1.0, 1.0, 1.0, 2.0, 7.0] } df = pd.DataFrame(data) df['date'] = pd.to_datetime(df['date']) # 确保日期列是datetime类型 # 生成分组ID current_sum = 0 group_id = 0 group_list = [] for dif_val in df['dif']: current_sum += dif_val group_list.append(group_id) # 当累加和达到或超过7时,切换到下一组,重置累加和 if current_sum >= 7: group_id += 1 current_sum = 0 df['group'] = group_list # 查看分组结果 for idx, group in df.groupby('group'): print(f"=== 第{idx+1}组 ===") print(group[['date', 'groc', 'dif']])
运行后会完全符合你的预期:
- 第1组包含行2-6(对应示例索引0-4),
dif累加和刚好为7 - 第2组包含行7-10(对应示例索引5-8),
dif累加和为11,直接全部纳入组内
方法二:Pandas向量化法(无循环,适合大数据)
如果你的DataFrame行数特别多,想用上Pandas的向量化效率,可以试试这个方法,逻辑稍微绕一点,但性能更优:
import pandas as pd import numpy as np # 同样先准备数据(省略重复部分) df['date'] = pd.to_datetime(df['date']) # 计算dif的累积和 cum_dif = df['dif'].cumsum() # 标记每个分组的结束点:当当前累积与上一个分组结束点的差值≥7时 group_end_mask = (cum_dif - cum_dif.where(cum_dif >=7).ffill().fillna(0)) >=7 # 分组ID就是结束点标记的累积和 df['group'] = group_end_mask.cumsum() # 后续可按group进行分组统计或其他操作 grouped = df.groupby('group')
这个方法用向量化操作替代了Python循环,避免了小数据量感知不到但大数据量会凸显的性能开销,数据规模越大优势越明显。
总结
- 如果你追求可读性和易维护性,方法一绝对是首选,逻辑和你的需求完全对齐,几乎不会出错;
- 如果你处理的是超大数据集,方法二的向量化操作能帮你显著提升运行效率。
内容的提问来源于stack exchange,提问作者Nicolò Retis
相关产品推荐
相关产品推荐

