为每个实体在数据框中添加行以减少丢失天数

时间:2019-12-13 11:47:37

标签: python pandas dataframe missing-symbols

我有以下问题:我的数据框看起来像这样:

ID Date        Value

1 2016-06-12   2
1 2016-06-13   2.5
1 2016-06-16   4
2 2016-06-12   3
2 2016-06-15   1.5

您可以看到我的数据中缺少日期。所以我更希望这样:

ID Date        Value

1 2016-06-12   2
1 2016-06-13   2.5
1 2016-06-14   NaN
1 2016-06-15   NaN
1 2016-06-16   4
2 2016-06-12   3
2 2016-06-13   NaN
2 2016-06-14   NaN
2 2016-06-15   1.5

为了解决这个问题,我做了以下事情:

df_new = df.groupby('ID').apply(lambda x: x.set_index('Date').resample('1D').first())

此解决方案有效,但是大约需要半小时来处理大型数据集。因此,我想知道是否有更好的解决方案?

1 个答案:

答案 0 :(得分:0)

第一个想法是创建IDDate值的所有可能组合,然后与左连接合并:

from  itertools import product

df['Date'] = pd.to_datetime(df['Date'])

L = list(product(df['ID'].unique(), pd.date_range(df['Date'].min(), df['Date'].max())))

df = pd.DataFrame(L, columns=['ID','Date']).merge(df, how='left')
print (df)
   ID       Date  Value
0   1 2016-06-12    2.0
1   1 2016-06-13    2.5
2   1 2016-06-14    NaN
3   1 2016-06-15    NaN
4   1 2016-06-16    4.0
5   2 2016-06-12    3.0
6   2 2016-06-13    NaN
7   2 2016-06-14    NaN
8   2 2016-06-15    1.5
9   2 2016-06-16    NaN

或使用DataFrame.reindex,但性能应更差,具体取决于数据:

df['Date'] = pd.to_datetime(df['Date'])

mux = pd.MultiIndex.from_product([df['ID'].unique(), 
                                  pd.date_range(df['Date'].min(), df['Date'].max())],
                                  names=['ID','Date'])

df = df.set_index(['ID','Date']).reindex(mux).reset_index()
print (df)
   ID       Date  Value
0   1 2016-06-12    2.0
1   1 2016-06-13    2.5
2   1 2016-06-14    NaN
3   1 2016-06-15    NaN
4   1 2016-06-16    4.0
5   2 2016-06-12    3.0
6   2 2016-06-13    NaN
7   2 2016-06-14    NaN
8   2 2016-06-15    1.5
9   2 2016-06-16    NaN