我有一个熊猫数据框,其中有一个ID的观测值,并且我遇到的问题与解决的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 ...
这是,我需要将周作为一列,将类别作为行,并且还需要填补无观察值的星期的空白。就我而言,我也需要几天的时间,但我想这确实很相似。
谢谢
答案 0 :(得分: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
答案 1 :(得分: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 :(得分:1)
这是使用groupby
和pivot
的一种方法:
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
。