我有一个与此类似的数据集:
import pandas as pd
data = pd.DataFrame({'id': [1, 3, 1, 2, 1, 3],
'date': ['2018-01-01 10:00', '2018-01-01 10:00', '2018-01-01 11:00',
'2018-01-01 11:00', '2018-01-01 12:00', '2018-01-01 12:00']})
data.date = pd.to_datetime(data.date)
输出:
date id
0 2018-01-01 10:00:00 1
1 2018-01-01 10:00:00 3
2 2018-01-01 11:00:00 1
3 2018-01-01 11:00:00 2
4 2018-01-01 12:00:00 1
5 2018-01-01 12:00:00 3
对于每个id,有三个可能的观察点。但是,并非每个点都存在。我想转换数据,使所有ID具有相同数量的观察。应该有一个额外的var,表明观察结果是否原来是空的。我想要的输出是这样的:
date id empty_obs
0 2018-01-01 10:00:00 1 0
1 2018-01-01 10:00:00 2 1
2 2018-01-01 10:00:00 3 0
3 2018-01-01 11:00:00 1 0
4 2018-01-01 11:00:00 2 0
5 2018-01-01 11:00:00 3 1
6 2018-01-01 12:00:00 1 0
7 2018-01-01 12:00:00 2 1
8 2018-01-01 12:00:00 3 0
目前我唯一的想法是创建一个像这样的DateRange:
period = pd.DataFrame(pd.date_range(data.date.min(), periods=3, freq='H' ))
然后以某种方式将其与分组数据版本合并。但是,这似乎不可能。
我确信那里有一个简单的解决方案。我很感激任何暗示!
答案 0 :(得分:2)
IIUC
data.assign(empty_obs=0).set_index(['date','id']).unstack().stack(dropna=False).fillna(1).reset_index()
Out[73]:
date id empty_obs
0 2018-01-01 10:00:00 1 0.0
1 2018-01-01 10:00:00 2 1.0
2 2018-01-01 10:00:00 3 0.0
3 2018-01-01 11:00:00 1 0.0
4 2018-01-01 11:00:00 2 0.0
5 2018-01-01 11:00:00 3 1.0
6 2018-01-01 12:00:00 1 0.0
7 2018-01-01 12:00:00 2 1.0
8 2018-01-01 12:00:00 3 0.0
答案 1 :(得分:2)
您还可以使用groupby
+ size
,然后使用@Wen演示的unstack
/ stack
惯用语:
data.groupby(['date', 'id'])\
.size()\
.unstack(fill_value=0)\
.stack()\
.reset_index(name='empty_obs')
date id empty_obs
0 2018-01-01 10:00:00 1 1
1 2018-01-01 10:00:00 2 0
2 2018-01-01 10:00:00 3 1
3 2018-01-01 11:00:00 1 1
4 2018-01-01 11:00:00 2 1
5 2018-01-01 11:00:00 3 0
6 2018-01-01 12:00:00 1 1
7 2018-01-01 12:00:00 2 0
8 2018-01-01 12:00:00 3 1