按 ID 分组并完成时间序列 Pandas [重复]

Posted

技术标签:

【中文标题】按 ID 分组并完成时间序列 Pandas [重复]【英文标题】:Group by ID and complet time series Pandas [duplicate] 【发布时间】:2019-03-12 11:12:41 【问题描述】:

我有一个观察到一个 ID 的 pandas 数据框,我遇到的问题类似于 here 解决的问题。

Timestamp              ID
2014-10-16 15:05:17    123
2014-10-16 14:56:37    148
2014-10-16 14:25:16    123
2014-10-16 14:15:32    123
2014-10-16 13:41:01    123
2014-10-16 12:50:30    148
2014-10-16 12:28:54    123
2014-10-16 12:26:56    123
2014-10-16 12:25:12    123
...
2014-10-08 15:52:49    150
2014-10-08 15:04:50    150
2014-10-08 15:03:48    148
2014-10-08 15:02:27    200
2014-10-08 15:01:56    236
2014-10-08 13:27:28    147
2014-10-08 13:01:08    148
2014-10-08 12:52:06    999
2014-10-08 12:43:27    999
Name: summary, Length: 600

在提到的帖子中,他们展示了如何按 ID 分组以及如何进行计数。使用 df['Week/Year'] = df['Timestamp'].apply(lambda x: "%d/%d" % (x.week, x.year)) 我现在有了这个:

   Timestamp               ID     Week/Year
0  2014-10-16 15:05:17     123    42/2014
1  2014-10-16 14:56:37     150    42/2014
2  2014-10-16 14:25:16     123    42/2014

我的问题是现在我想制作一个时间序列,所以实际上我需要:

Category    Week_42_2014    Week_43_2014    Week_44_2014    
123         7              0              6
150         0              0              2              ...

也就是说,我需要将周作为一列,将类别作为行,并且还要在没有观察的情况下填补周的空白。就我而言,我也需要几天,但我想它真的很相似。

谢谢,

【问题讨论】:

这个问题已被标记为重复,因为我的问题不清楚。我不想只是旋转数据,我还打算用所有 ID 的 0 来填补缺失的几周和没有观察的日子。我改变了原来的解释,让自己更清楚。 我回滚了你的编辑,因为你不应该在你得到答案后更改你的问题。相反,请使用 minimal reproducible example 提出新问题,以免出现这些问题。 它已经在文本中(“并且还填补了没有观察的几周的空白”),我只是让它更清楚。所以,在我看来,问题的实质没有改变。不过好的,下次我会尽量说清楚一点。 【参考方案1】:

你可以使用pd.crosstab来做任务

df['date'] = pd.date_range(start='2014-10-16 15:05:17 ',end='2014-11-08 12:43:27 ',freq='D')
df['value'] = np.repeat([11,22,33,44],len(df)/3)[:len(df)]
df['week'] = df.date.dt.week
df['Year'] = df.date.dt.year



df = pd.crosstab(df.value,[df.week,df.Year])
df.columns = 'Week_' +df.columns.levels[0].astype(str)+"_" +df.columns.levels[1].astype(str)

输出:

    Week_42_2014    Week_43_2014    Week_44_2014    Week_45_2014
value               
11  4   3   0   0
22  0   4   3   0
33  0   0   4   3
44  0   0   0   2

【讨论】:

【参考方案2】:

这是使用groupbypivot 的一种方法:

df = df.groupby(['ID', pd.Grouper(key = 'Timestamp', freq = 'W')] ['ID'].count().\
        to_frame().rename(columns = 'ID' : 'counts').reset_index()

然后pivot:

df.pivot(index = 'ID', columns = 'Timestamp', values = 'counts')

这当然会将列名作为相应周的第一天返回;您可以通过将df.columns 替换为所需列名的列表来更改这些。

编辑:

如果您已经有一周的专栏,您可以只使用pd.pivot_table 而无需使用groupby

【讨论】:

【参考方案3】:

你可以使用pd.pivot_table:

res = df.pivot_table(index='ID', columns='Week/Year', aggfunc='count', fill_value=0)

print(res)

          Timestamp        
Week/Year   41/2014 42/2014
ID                         
123               0       7
147               1       0
148               2       2
150               2       0
200               1       0
236               1       0
999               2       0

【讨论】:

以上是关于按 ID 分组并完成时间序列 Pandas [重复]的主要内容,如果未能解决你的问题,请参考以下文章

Pandas数据框按顺序分组[重复]

按 10 分钟间隔对 pandas DataFrame 进行分组[重复]

Pandas按组内的值分组和排序[重复]

按连续计数 Pandas Python 分组 [关闭]

Pandas:在两个不同时间序列中按日期顺序分组在同一 ID 下的列表中显示事件

按两个参数对字典列表进行分组并计算分组值