假设我有下表:
ProdID Date Val1 Val2 Val3
Prod1 4/1/2019 1 3 4
Prod1 4/3/2019 2 3 54
Prod1 4/4/2019 3 4 54
Prod2 4/1/2019 1 3 3
Prod2 4/2/2019 1 3 4
Prod2 4/3/2019 2 4 4
Prod2 4/4/2019 2 5 3
Prod2
条目已正确填充,因为我们已将数据从4/1/2019
到4/4/2019
。
Prod1
缺少1个日期-4/2/2019
。
我想找到所有ProdID的缺失日期,并使用从上一个条目的最后一个复制的数据填充Val1-3。例如,我想将数据从4/1/2019
复制到4/2/2019
ProdID Date Val1 Val2 Val3
Prod1 4/1/2019 1 3 4
Prod1 4/2/2019 1 3 4
Prod1 4/3/2019 2 3 54
Prod1 4/4/2019 3 4 54
Prod2 4/1/2019 1 3 3
Prod2 4/2/2019 1 3 4
Prod2 4/3/2019 2 4 4
Prod2 4/4/2019 2 5 3
答案 0 :(得分:5)
首先通过to_datetime
将列转换为datetime
,然后通过DataFrame.set_index
创建DatetimeIndex
并使用GroupBy.apply
调用DataFrame.asfreq
-还有可能指定向前或向后填充缺失值的方法:
df['Date'] = pd.to_datetime(df['Date'])
df1 = (df.set_index('Date')
.groupby('ProdID')
.apply(lambda x: x.asfreq('D', method='ffill'))
.reset_index(level=0, drop=True)
.reset_index()
.reindex(df.columns, axis=1))
print (df1)
ProdID Date Val1 Val2 Val3
0 Prod1 2019-04-01 1 3 4
1 Prod1 2019-04-02 1 3 4
2 Prod1 2019-04-03 2 3 54
3 Prod1 2019-04-04 3 4 54
4 Prod2 2019-04-01 1 3 3
5 Prod2 2019-04-02 1 3 4
6 Prod2 2019-04-03 2 4 4
7 Prod2 2019-04-04 2 5 3
另一种解决方案是通过product
和DataFrame.merge
通过左连接创建乘积和datetimes
的所有组合,最后通过ffill
来填充缺失值:
dates = pd.date_range(start=df['Date'].min(), end=df['Date'].max())
prods = df.ProdID.unique()
from itertools import product
df1 = pd.DataFrame(list(product(prods, dates)), columns=['ProdID', 'Date'])
print (df1)
ProdID Date
0 Prod1 2019-04-01
1 Prod1 2019-04-02
2 Prod1 2019-04-03
3 Prod1 2019-04-04
4 Prod2 2019-04-01
5 Prod2 2019-04-02
6 Prod2 2019-04-03
7 Prod2 2019-04-04
df = df1.merge(df, how='left').ffill()
print (df)
ProdID Date Val1 Val2 Val3
0 Prod1 2019-04-01 1.0 3.0 4.0
1 Prod1 2019-04-02 1.0 3.0 4.0
2 Prod1 2019-04-03 2.0 3.0 54.0
3 Prod1 2019-04-04 3.0 4.0 54.0
4 Prod2 2019-04-01 1.0 3.0 3.0
5 Prod2 2019-04-02 1.0 3.0 4.0
6 Prod2 2019-04-03 2.0 4.0 4.0
7 Prod2 2019-04-04 2.0 5.0 3.0
答案 1 :(得分:0)
您还可以像这样使用pandas.MultiIndex.from_product
,DataFrame.reindex
和DataFrame.ffill
:
df['Date'] = pd.to_datetime(df['Date'])
dates = pd.date_range(start=df.Date.min(), end=df.Date.max(), freq='1D')
idx = pd.MultiIndex.from_product([df.ProdID.unique(), dates], names=['ProdID', 'Date'])
df.set_index(['ProdID', 'Date']).reindex(idx).ffill().reset_index()
[输出]
ProdID Date Val1 Val2 Val3
0 Prod1 2019-04-01 1.0 3.0 4.0
1 Prod1 2019-04-02 1.0 3.0 4.0
2 Prod1 2019-04-03 2.0 3.0 54.0
3 Prod1 2019-04-04 3.0 4.0 54.0
4 Prod2 2019-04-01 1.0 3.0 3.0
5 Prod2 2019-04-02 1.0 3.0 4.0
6 Prod2 2019-04-03 2.0 4.0 4.0
7 Prod2 2019-04-04 2.0 5.0 3.0