按日期和唯一用户数量对多个变量进行分组

时间:2019-11-27 13:35:01

标签: python pandas dataframe pandas-groupby

我有一个包含推文的数据框。我有一些列,其中包含有关日期时间的信息,有关唯一的user_id的信息,然后包含指示该推文是否属于主题类别的列。最后,我想用折线图将其可视化。

数据如下:

                 datetime             user_id  Meta  News & Media  Environment  ...
0     2019-05-08 07:16:02            21741359   NaN           NaN          1.0
1     2019-05-08 07:15:23          2785265103   NaN           NaN          1.0
2     2019-05-08 07:14:11           606785697   NaN           1.0          NaN
3     2019-05-08 07:13:42  718989200616529921   1.0           NaN          NaN
4     2019-05-08 07:13:27  939207240728350720   1.0           NaN          1.0
...                   ...                 ...   ...           ...          ...

到目前为止,我已经设法通过每天用以下代码对每个主题进行汇总:

monthly_trends = tweets_df.groupby(pd.Grouper(key='datetime', freq='D'))[list(issues.keys())].sum().fillna(0)

这给了我

             Meta  News & Media   Environment  ...
datetime                                                                
2019-05-07  586.0          25.0          30.0      
2019-05-08  505.0          16.0          70.0      
2019-05-09  450.0          12.0          50.0     
2019-05-10  339.0           8.0          90.0               
2019-05-11  254.0           5.0          10.0    

我通过以下方式绘制该图

monthly_trends.plot(kind='line', figsize=(20,10), linewidth=5, fontsize=20)
plt.xlabel('Date', fontsize=20)
plt.title('Issue activity during the election period', size = 30)
plt.show()

哪个给我一个漂亮的图表。但是由于一个用户可能只是在散布一个主题,所以我想统计每天每个主题的唯一身份用户的频率。我试过使用其他groupby,但只有错误。

2 个答案:

答案 0 :(得分:1)

堆叠所有问题,按问题和日期分组,并计算唯一的用户ID:

df.columns.names = ['issue']
df_users = (df.set_index(['datetime', 'user_id'])[issues]
              .stack()
              .reset_index().groupby([pd.Grouper(key='datetime', freq='D'), 'issue'])
              .apply(lambda x: len(x.user_id.unique()))
              .rename('n_unique_users').reset_index())
print(df_users)

    datetime         issue  n_unique_users
0 2019-05-08   Environment               3
1 2019-05-08          Meta               2
2 2019-05-08  News & Media               1

然后您可以根据需要重塑图形:

df_users.pivot_table(index='datetime', columns='issue', values='n_unique_users', aggfunc=sum)

issue       Environment  Meta  News & Media
datetime                                   
2019-05-08            3     2             1

答案 1 :(得分:1)

对于跨多个系列的熊猫DataFrame.plot,您需要具有单独列的宽格式数据。但是,对于唯一的 user_id 计算,您需要长格式的数据进行聚合。因此,请考虑meltgroupby,然后再考虑pivot进行绘图。如果您不需要

### RESHAPE LONG AND AGGREGATE      
long_df = (tweets_df.melt(id_vars=['datetime', 'user_id'], 
                          value_name = 'Count', var_name = 'Issue')
                    .query("Count >= 1")
                    .groupby([pd.Grouper(key='datetime', freq='D'), 'Issue'])['user_id'].nunique()
                    .reset_index()
          )

### RESHAPE WIDE AND PLOT
(long_df.pivot(index='datetime', columns='Issue', values='user_id')
        .plot(kind='line', title='Unique Users by Day and Tweet Issue')
)

plt.show()
plt.clf()
plt.close()