如何在Pandas DataFrame中无循环计算有效连续记录的日期差平均值
无循环实现连续A类水果日期差平均值计算
处理步骤
转换日期格式并排序
先将Date列转为datetime类型,再按水果和日期排序,确保连续记录的时间顺序正确:import pandas as pd # 转换日期列 df['Date'] = pd.to_datetime(df['Date']) # 按水果+日期排序 df_sorted = df.sort_values(['fruits', 'Date']).reset_index(drop=True)标记连续Quality分组
通过对比当前行与上一行的Quality值,生成连续块的分组ID,方便后续识别连续的A序列:df_sorted['group_id'] = (df_sorted['Quality'] != df_sorted['Quality'].shift()).cumsum()筛选有效连续A对
只保留Quality为A的记录,然后对每个连续A块内的行编号,仅保留每个块的第一行(对应与第二行构成的有效对,排除连续A序列中超过两条的后续行):# 筛选A类记录并给每个连续块内的行编号 a_records = df_sorted[df_sorted['Quality'] == 'A'] a_records['row_num'] = a_records.groupby('group_id').cumcount() # 仅保留每个连续A块的第一行(对应和第二行的有效对) valid_pairs_head = a_records[a_records['row_num'] == 0]计算日期差并求平均值
计算有效行与下一行的日期差,再按水果分组求平均值,最后与所有水果做左连接,确保无有效对的水果显示null:# 计算日期差 valid_pairs_head['time_diff'] = valid_pairs_head['Date'].shift(-1) - valid_pairs_head['Date'] # 按水果分组求平均 avg_diff = valid_pairs_head.groupby('fruits')['time_diff'].mean().reset_index(name='avg time diff') # 左连接所有水果,补全无有效对的null值 final_result = df[['fruits']].drop_duplicates().merge(avg_diff, on='fruits', how='left')
示例验证
假设输入示例数据:
data = { 'sn': [1,2,3,4,5,6,7,8], 'fruits': ['Apple','Apple','Apple','Apple','Banana','Banana','Orange','Orange'], 'Quality': ['A','A','B','A','A','B','B','A'], 'Date': ['2023-01-01','2023-01-16','2023-01-30','2023-02-14','2023-01-05','2023-01-20','2023-01-10','2023-01-25'] } df = pd.DataFrame(data)
运行上述代码后,final_result的输出为:
| fruits | avg time diff |
|---|---|
| Apple | 15 days |
| Banana | NaN |
| Orange | NaN |
完全符合需求。
内容的提问来源于stack exchange,提问作者Engineer
相关产品推荐
相关产品推荐

