原始
user_id date had_session made_an_order
1 2016-03-01 True True
2016-03-02 True True
2016-03-03 True False
2 2016-03-01 True True
2016-03-02 True True
2016-03-04 True False
3 2016-03-01 True False
2016-03-04 True False
回填数据
user_id date had_session made_an_order
1 2016-03-01 True True
2016-03-02 True True
2016-03-03 True False
2016-03-04 False False # backfilled row
2 2016-03-01 True True
2016-03-02 True True
2016-03-03 False False # backfilled row
2016-03-04 True False
3 2016-03-01 True False
2016-03-02 False False # backfilled row
2016-03-03 False False # backfilled row
2016-03-04 True False
我的数据有两个级别:第一级是user_id
,第二级是他们是否有会话。
我想确保数据被回填,以便第二级包含每个可能的日期并默认为false
e.g。可能的日期是2016-03-01至2016-03-04。所以我想确保每个user_id都有这些日期
答案 0 :(得分:2)
您可以先reset_index
,然后pivot
fillna
,最后unstack
:
print (df.reset_index()
.pivot(index='date',columns='user_id',values='had_session')
.fillna(False)
.unstack()
.reset_index(name='had_session'))
user_id date had_session
0 1 2016-03-01 True
1 1 2016-03-02 True
2 1 2016-03-03 True
3 1 2016-03-04 False
4 2 2016-03-01 True
5 2 2016-03-02 True
6 2 2016-03-03 False
7 2 2016-03-04 True
8 3 2016-03-01 True
9 3 2016-03-02 False
10 3 2016-03-03 False
11 3 2016-03-04 True
说明:
#remove multiindex
print (df.reset_index())
user_id date had_session
0 1 2016-03-01 True
1 1 2016-03-02 True
2 1 2016-03-03 True
3 2 2016-03-01 True
4 2 2016-03-02 True
5 2 2016-03-04 True
6 3 2016-03-01 True
7 3 2016-03-04 True
#pivot table - get NaN in missing values
print (df.reset_index()
.pivot(index='date',columns='user_id',values='had_session'))
user_id 1 2 3
date
2016-03-01 True True True
2016-03-02 True True None
2016-03-03 True None None
2016-03-04 None True True
#replace NaN to False
print (df.reset_index()
.pivot(index='date',columns='user_id',values='had_session')
.fillna(False))
user_id 1 2 3
date
2016-03-01 True True True
2016-03-02 True True False
2016-03-03 True False False
2016-03-04 False True True
#create multiindex
print (df.reset_index()
.pivot(index='date',columns='user_id',values='had_session')
.fillna(False)
.unstack())
user_id date
1 2016-03-01 True
2016-03-02 True
2016-03-03 True
2016-03-04 False
2 2016-03-01 True
2016-03-02 True
2016-03-03 False
2016-03-04 True
3 2016-03-01 True
2016-03-02 False
2016-03-03 False
2016-03-04 True
dtype: bool
有2列的解决方案:
df1 = (df.reset_index()
.pivot_table(index='date',columns='user_id',values=['had_session', 'made_an_order'])
.fillna(False))
df2 = (df1.had_session)
df3 = (df1.made_an_order)
print (pd.concat([df2.unstack(),df3.unstack()],
axis=1,
keys=['had_session','made_an_order']))
had_session made_an_order
user_id date
1 2016-03-01 True True
2016-03-02 True True
2016-03-03 True False
2016-03-04 False False
2 2016-03-01 True True
2016-03-02 True True
2016-03-03 False False
2016-03-04 True False
3 2016-03-01 True False
2016-03-02 False False
2016-03-03 False False
2016-03-04 True False
另一个双pivot
的解决方案:
df2 = (df.reset_index()
.pivot(index='date',columns='user_id',values='had_session')
.fillna(False))
df3 = (df.reset_index()
.pivot(index='date',columns='user_id',values='made_an_order')
.fillna(False))
print (pd.concat([df2.unstack(),df3.unstack()],
axis=1,
keys=['had_session','made_an_order']))
had_session made_an_order
user_id date
1 2016-03-01 True True
2016-03-02 True True
2016-03-03 True False
2016-03-04 False False
2 2016-03-01 True True
2016-03-02 True True
2016-03-03 False False
2016-03-04 True False
3 2016-03-01 True False
2016-03-02 False False
2016-03-03 False False
2016-03-04 True False
答案 1 :(得分:1)
你可以这样做:
来源DF
In [370]: a
Out[370]:
had_session made_an_order
user_id date
1 2016-03-01 True True
2016-03-02 True True
2016-03-03 True False
2 2016-03-01 True True
2016-03-02 True True
2016-03-04 True False
3 2016-03-01 True False
2016-03-04 True False
使用MultiIndex准备DF,其中包含user_id和日期的产品:
In [371]: df = pd.DataFrame(
.....: index=pd.MultiIndex.from_product([
.....: a.index.get_level_values('user_id').unique().tolist(),
.....: a.index.get_level_values('date').unique().tolist()
.....: ])
.....: )
从原始/源DF
设置索引名称In [372]: df.index.names=a.index.names
加入
In [374]: df.join(a, how='left').fillna(False)
Out[374]:
had_session made_an_order
user_id date
1 2016-03-01 True True
2016-03-02 True True
2016-03-03 True False
2016-03-04 False False
2 2016-03-01 True True
2016-03-02 True True
2016-03-03 False False
2016-03-04 True False
3 2016-03-01 True False
2016-03-02 False False
2016-03-03 False False
2016-03-04 True False