Pandas按ID分组计算DataFrame首尾时间戳差值的方法
Pandas分组计算推文生命周期实现方案
首先先做前置类型校验,确保时间列格式正确,否则时间差计算会报错:
import pandas as pd # 将时间字段统一转换为pandas内置的datetime类型 df['retweet_datetime'] = pd.to_datetime(df['retweet_datetime']) df['tweet_datetime'] = pd.to_datetime(df['tweet_datetime'])
你的数据集已经提前按retweet_datetime从新到旧降序排列,因此每个tweet_id分组内:
- 第一条记录的
retweet_datetime就是该推文最晚转发时间 - 最后一条记录的
retweet_datetime就是该推文最早转发时间 - 同组内
tweet_datetime是固定的推文发布时间,取任意一条记录的值即可
直接用分组聚合就能得到每个tweet_id对应一行的结果,核心代码如下:
result_df = df.groupby('tweet_id', as_index=False).agg( # 末次转发时间减首次转发时间,得到首次转发到末次转发的跨度 tweet_lifetime1 = ('retweet_datetime', lambda x: x.iloc[0] - x.iloc[-1]), # 末次转发时间减推文发布时间,得到发布到末次转发的跨度 tweet_lifetime2 = ('retweet_datetime', lambda x: x.iloc[0] - df.loc[x.index, 'tweet_datetime'].iloc[0]) )
如果需要把输出的timedelta类型转换成你示例里04:16:55这种时:分:秒的字符串格式,追加以下处理代码即可:
# 统一格式化时间差为HH:MM:SS格式 for col in ['tweet_lifetime1', 'tweet_lifetime2']: result_df[col] = result_df[col].dt.components.apply( lambda row: f"{row.hours:02d}:{row.minutes:02d}:{row.seconds:02d}", axis=1 )
补充说明:如果后续数据没有提前排序,也可以不依赖预先排序的逻辑,把聚合逻辑改成取组内
retweet_datetime的最大值减最小值计算tweet_lifetime1,最大值减tweet_datetime计算tweet_lifetime2,代码鲁棒性更强,写法如下:result_df = df.groupby('tweet_id', as_index=False).agg( tweet_datetime = ('tweet_datetime', 'first'), latest_retweet = ('retweet_datetime', 'max'), earliest_retweet = ('retweet_datetime', 'min') ).assign( tweet_lifetime1 = lambda x: x['latest_retweet'] - x['earliest_retweet'], tweet_lifetime2 = lambda x: x['latest_retweet'] - x['tweet_datetime'] ).drop(columns=['latest_retweet', 'earliest_retweet', 'tweet_datetime'])
你之前用的df.groupby('tweet_id')['retweet_datetime'].diff()是计算组内相邻两行的时间差,适合统计相邻两次转发的间隔,和当前需要的组内首尾全局差值的场景逻辑不同,用上述聚合方案可以直接得到目标结果。
内容的提问来源于stack exchange,提问作者mOna
相关产品推荐
相关产品推荐

