我有一个数据框:
Date Scenario Value
2018-08-08 S1 120
2018-08-08 S2 132
2018-08-08 S3 127
2018-08-09 S1 114
2018-08-09 S3 107
2018-08-09 S4 201
...
我想拥有的是:
Date Scenario Value
2018-08-08 S1 120
2018-08-08 S2 132
2018-08-08 S3 127
2018-08-08 S4 0
2018-08-09 S1 114
2018-08-08 S2 0
2018-08-09 S3 107
2018-08-09 S4 201
...
所以有一种模式。每天有4种情况。每个都必须在那里!如果它们不存在,我需要创建一个缺少日期和场景的行,并将0
分配给相应的Value
列。有什么建议么?谢谢!
答案 0 :(得分:0)
一种方法是使用前两列定义df2,然后使用:
pd.merge(df, df2, how='outer', on=['Date','Scenario']).fillna(0)
答案 1 :(得分:0)
我们可以先做pivot
然后做stack
s=df.pivot(*df.columns).stack(dropna=False).fillna(0).reset_index()
s
Date Scenario 0
0 2018-08-08 S1 120.0
1 2018-08-08 S2 132.0
2 2018-08-08 S3 127.0
3 2018-08-08 S4 0.0
4 2018-08-09 S1 114.0
5 2018-08-09 S2 0.0
6 2018-08-09 S3 107.0
7 2018-08-09 S4 201.0
答案 2 :(得分:0)
最近我不得不做一些非常相似的事情。
您需要的是使用pd.date_range,使用您希望日期走多远的最大日期。
date_range = pd.date_range(start=min_date, end=max_date)
df = df.set_index('Date').reindex(date_range).fillna(0).rename_axis('Date').reset_index()
您必须确保以尽可能最细的深度进行此操作
答案 3 :(得分:0)
创建所有可能的l
值的列表Scenario
。根据{{1}}和唯一值idx
构造一个多索引l
。最后,在df.Date
和set_index
上Date
并使用Scenario
和idx
reset_index
或者另一种方法是从上方的l = ['S1', 'S2', 'S3', 'S4']
idx = pd.MultiIndex.from_product([df.Date.unique(), l])
(df.set_index(['Date', 'Scenario']).reindex(idx, fill_value=0)
.rename_axis(['Date', 'Scenarios'])
.reset_index())
Out[498]:
Date Scenarios Value
0 2018-08-08 S1 120
1 2018-08-08 S2 132
2 2018-08-08 S3 127
3 2018-08-08 S4 0
4 2018-08-09 S1 114
5 2018-08-09 S2 0
6 2018-08-09 S3 107
7 2018-08-09 S4 201
构造一个数据帧,并将idx
与left
和df
合并。但是,此方法不像上面的fillna
方法那样干净。