如何用Pandas GroupBy计算用户每小时平均发推数?
计算用户每小时平均发推数
我有一个大型Twitter数据集,想要计算用户每小时的平均发推数。已经通过user_id和created_at(发推时间戳)字段排序后,以user_id、created_at的年、月、日、小时为维度完成分组,代码如下:
grouped_df = tweets_df.sort_values(["created_at"]).groupby([ tweets_df['user_id'], tweets_df['created_at'].dt.year, tweets_df['created_at'].dt.month, tweets_df['created_at'].dt.day, tweets_df['created_at'].dt.hour])
通过grouped_df["created_at"].count()已经得到每小时每用户的发推计数,现在需要对每个用户的所有小时发推数计算平均值,期望输出格式如下:
user_id average_tweets_per_hour 678033 4 665353 10
附带可复现代码示例:
import pandas as pd import numpy as np df_t = pd.DataFrame({'id_t': [0, 1, 2, 3], 'id_u': [1, 1, 1, 2], 'timestamp': ["2019-06-27 11:12:32", "2019-06-27 11:14:32", "2020-07-28 11:24:32", "2020-02-27 13:30:21"]}) print(df_t) df_u = pd.DataFrame({'id_u': [1, 2]}) print() print(df_u) df_u_new = pd.DataFrame({'id_u': [1, 2], 'avg_t_per_h': [2, 1]}) print() print(df_u_new)
解决方案
步骤1:处理时间戳并完成小时级计数
先确保时间戳字段是datetime类型,再按用户+小时维度分组统计每小时发推数:
# 转换timestamp为datetime类型(若未转换) df_t['timestamp'] = pd.to_datetime(df_t['timestamp']) # 按用户id和小时维度分组,统计每小时发推数 hourly_counts = df_t.groupby([ 'id_u', df_t['timestamp'].dt.year, df_t['timestamp'].dt.month, df_t['timestamp'].dt.day, df_t['timestamp'].dt.hour ])['id_t'].count().reset_index(name='tweets_per_hour')
步骤2:计算每个用户的小时平均发推数
基于小时计数结果,按用户id分组求平均值:
user_avg = hourly_counts.groupby('id_u')['tweets_per_hour'].mean().reset_index(name='avg_t_per_h')
步骤3:匹配所有用户(含无发推记录的用户)
如果需要和df_u中的所有用户匹配(无发推记录的用户平均值设为0),使用左连接并填充空值:
df_u_new = df_u.merge(user_avg, on='id_u', how='left').fillna(0) # 转换为整数格式(可选) df_u_new['avg_t_per_h'] = df_u_new['avg_t_per_h'].astype(int)
完整可运行代码
import pandas as pd import numpy as np df_t = pd.DataFrame({'id_t': [0, 1, 2, 3], 'id_u': [1, 1, 1, 2], 'timestamp': ["2019-06-27 11:12:32", "2019-06-27 11:14:32", "2020-07-28 11:24:32", "2020-02-27 13:30:21"]}) df_u = pd.DataFrame({'id_u': [1, 2]}) # 转换时间戳类型 df_t['timestamp'] = pd.to_datetime(df_t['timestamp']) # 统计每小时发推数 hourly_counts = df_t.groupby([ 'id_u', df_t['timestamp'].dt.year, df_t['timestamp'].dt.month, df_t['timestamp'].dt.day, df_t['timestamp'].dt.hour ])['id_t'].count().reset_index(name='tweets_per_hour') # 计算用户平均 user_avg = hourly_counts.groupby('id_u')['tweets_per_hour'].mean().reset_index(name='avg_t_per_h') # 匹配所有用户 df_u_new = df_u.merge(user_avg, on='id_u', how='left').fillna(0).astype({'avg_t_per_h': int}) print(df_u_new)
运行后输出与示例中的df_u_new一致:
id_u avg_t_per_h 0 1 2 1 2 1
内容的提问来源于stack exchange,提问作者JayJona
相关产品推荐
相关产品推荐

