You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Pandas中按组计算月份差值并获取月度频次

问题

给定如下Pandas DataFrame:

import pandas as pd

data = pd.DataFrame([['1001','2020-03-06'],
                     ['1001','2020-04-06'],
                     ['1002','2021-04-02'],
                     ['1003','2022-07-08'],
                     ['1001','2020-09-06'],
                     ['1003','2022-04-04'],
                     ['1002','2021-06-05'],
                     ['1007','2020-09-08'],
                     ['1002','2021-12-07'],
                     ['1003','2022-12-06'],
                     ['1007','2020-02-10'],
                     ], 
                    columns=['Type', 'Date'])

需要按Type分组,计算每组内每个日期对应的月度频次数值(即该日期到组内下一个较晚日期的月份差值,最后一个日期差值为0),期望输出如下:

pd.DataFrame([['1007','2020-09-08', 0],
              ['1007','2020-02-10', 7],
              ['1003','2022-12-06', 0],
              ['1003','2022-07-08', 5],
              ['1003','2022-04-04', 3],
              ['1002','2021-12-07', 0],
              ['1002','2021-06-05', 6],
              ['1002','2021-04-02', 2],
              ['1001','2020-09-06', 0],
              ['1001','2020-04-06', 5],
              ['1001','2020-03-06', 1],
             ], 
             columns=['Type', 'Date', 'MonthlyFreq'])

当前尝试的代码未得到期望结果:

data['Date'] = pd.to_datetime(data['Date'])
data['diff'] = data.groupby(['Type'])['Date'].apply(lambda x:(x.max() - x)/np.timedelta64(1, 'M'))
data['diff'] = data['diff'].astype(int) 
data = data.sort_values('Type')
解决方案

你的代码计算的是每个日期与组内最大日期的月份差,但需求是每个日期到下一个最近的较晚日期的月份差。可以通过以下步骤实现:

  1. 转换日期为datetime类型,按Type分组后对每组内日期降序排序;
  2. 使用shift(-1)获取下一行的日期,计算两者的月份差值;
  3. 填充最后一行的空值为0并转为整数,最后调整排序匹配期望输出。

完整代码:

import pandas as pd
import numpy as np

# 初始化数据
data = pd.DataFrame([['1001','2020-03-06'],
                     ['1001','2020-04-06'],
                     ['1002','2021-04-02'],
                     ['1003','2022-07-08'],
                     ['1001','2020-09-06'],
                     ['1003','2022-04-04'],
                     ['1002','2021-06-05'],
                     ['1007','2020-09-08'],
                     ['1002','2021-12-07'],
                     ['1003','2022-12-06'],
                     ['1007','2020-02-10'],
                     ], 
                    columns=['Type', 'Date'])

# 转换日期格式
data['Date'] = pd.to_datetime(data['Date'])

# 定义分组计算逻辑
def compute_monthly_freq(group):
    # 组内按日期降序排列
    group_sorted = group.sort_values('Date', ascending=False).reset_index(drop=True)
    # 计算当前日期与下一个日期的月份差
    group_sorted['MonthlyFreq'] = (group_sorted['Date'].shift(-1) - group_sorted['Date']) / np.timedelta64(1, 'M')
    # 最后一行差值设为0,转为整数
    group_sorted['MonthlyFreq'] = group_sorted['MonthlyFreq'].fillna(0).astype(int)
    return group_sorted

# 应用分组计算
result = data.groupby('Type', group_keys=False).apply(compute_monthly_freq)

# 按Type降序、Date降序排序,匹配期望输出顺序
result = result.sort_values(['Type', 'Date'], ascending=[False, False])

# 可选:将日期转回字符串格式
result['Date'] = result['Date'].dt.strftime('%Y-%m-%d')

print(result)

运行后输出与期望一致:

Type        Date  MonthlyFreq
7   1007  2020-09-08            0
10  1007  2020-02-10            7
9   1003  2022-12-06            0
3   1003  2022-07-08            5
5   1003  2022-04-04            3
8   1002  2021-12-07            0
6   1002  2021-06-05            6
2   1002  2021-04-02            2
4   1001  2020-09-06            0
1   1001  2020-04-06            5
0   1001  2020-03-06            1

内容的提问来源于stack exchange,提问作者Hussain Madarwala

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.20 02:17:35