在分组后的DataFrame中计算连续行的月份时间差
高效计算Pandas DataFrame中用户连续日期的间隔月份数
针对你这个需求,我推荐用Pandas的分组+向量化时间运算来实现,既简洁又高效,完全适配你给出的场景(所有日期都是当月第一天)。
完整实现代码
import pandas as pd # 你的示例数据 df = pd.DataFrame({ 'name': ['Mark', 'Anne', 'Anne', 'Anne', 'Anne', 'Anne', 'John', 'John', 'John', 'Ethan'], 'date': ['2018-01-01', '2018-01-01', '2018-02-01', '2018-04-01', '2018-09-01', '2019-01-01', '2018-02-01', '2018-06-01', '2019-02-01', '2018-03-01'] }) # 1. 先把日期列转为datetime类型,这是时间计算的前提 df['date'] = pd.to_datetime(df['date']) # 2. 按用户分组,计算连续日期的月份间隔(精准版,因为都是当月第一天) df['months'] = df.groupby('name')['date'].apply( lambda x: (x.dt.year - x.shift().dt.year) * 12 + (x.dt.month - x.shift().dt.month) ) # 3. 把每个用户的第一行NaN填充为0,转成整数 df['months'] = df['months'].fillna(0).astype(int) print(df)
关键步骤解释
- 日期类型转换:必须先把字符串格式的
date转为datetime64类型,Pandas的时间运算API只对这个类型生效。 - 分组计算间隔:
- 用
groupby('name')把数据按用户拆分,确保只计算同一用户的连续行间隔。 - 因为所有日期都是当月第一天,我们可以直接通过年份差×12 + 月份差来计算间隔,这个方法完全精准,没有近似误差。
x.shift()用来获取当前组的上一行数据,和当前行做年份、月份的差值计算。
- 用
- 填充初始值:每个用户的第一行没有上一行数据,所以计算结果是
NaN,用fillna(0)把这些位置设为0,最后转成整数类型和预期输出一致。
性能说明
这个方案用的是Pandas的内置向量化操作,避免了手动循环,在数据量较大(比如几十万行)的时候,性能会比循环写法快几十倍甚至上百倍,完全符合高效的要求。
如果你想更简洁一点,也可以用时间差转秒数的近似写法(结果和精准版一致,因为都是当月第一天):
df['months'] = df.groupby('name')['date'].diff().dt.total_seconds() // (30*24*3600)
内容的提问来源于stack exchange,提问作者HRDSL
相关产品推荐
相关产品推荐

