问题:使用熊猫-如何相对于最小/最大日期值per组有效地用零值,每月(例如,最后一天编入索引)频率填充缺失的日期?
Edit不假定输入日期对应于该月的最后一天。要解决此问题,请在以下建议的答案中添加以下行:
df.date = df.date + pd.offsets.MonthEnd(0)
没有此修复程序,用freq ='M'填充值会导致NA的...!
注:熊猫0.24.2版
示例输入:
data = [{'name': 'A', 'date': '2019-01-01', 'val': 10},
{'name': 'A', 'date': '2019-04-30', 'val': 2},
{'name': 'B', 'date': '2019-02-15', 'val': 6},
{'name': 'B', 'date': '2019-05-01', 'val': 5}]
df = pd.DataFrame(data)
date name val
0 2019-01-01 A 10
1 2019-04-30 A 2
2 2019-02-15 B 6
3 2019-05-01 B 5
请注意,输入中的日期不一定是其相应月份的第一天或最后一天。
示例所需输出
date name val
0 2019-01-31 A 10
1 2019-02-28 A 0
2 2019-03-31 A 0
3 2019-04-30 A 2
4 2019-02-28 B 6
5 2019-03-31 B 0
6 2019-04-30 B 0
7 2019-05-31 B 5
尝试:
以下内容在索引级别有效,但用NA填充所有内容:
df['date'] = pd.to_datetime(df['date'])
dg = df.groupby('name').apply(lambda x: x.reindex(pd.date_range(min(x.date), max(x.date), freq='M')))
另外:
Pandas filling missing dates and values within group
以上链接的答案似乎与每个组都不相关,而是相对于整个数据集的最小/最大日期值。
我将使用groupby
,resample
和asfreq
(编辑:当您在非MonthEnd日期更新问题时。我根据您的建议添加了pd.offsets.MonthEnd
)]
df.date = df.date + pd.offsets.MonthEnd(0)
(df.set_index('date').groupby('name').resample('M')
.asfreq(fill_value=0).drop('name',1)
.reset_index())
Out[550]:
name date val
0 A 2019-01-31 10
1 A 2019-02-28 0
2 A 2019-03-31 0
3 A 2019-04-30 2
4 B 2019-02-28 6
5 B 2019-03-31 0
6 B 2019-04-30 0
7 B 2019-05-31 5
一个快速修复:
df.date = pd.to_datetime(df.date)
new_df = (df.set_index('date')
.groupby('name', as_index=False)
.apply(lambda x: x.resample('M').interpolate())
.reset_index(0, drop=True)
)
s = new_df['name'].isna()
new_df.loc[s, 'val'] = 0
new_df['name'] = new_df['name'].ffill()
输出:
name val
date
2019-01-31 A 10.0
2019-02-28 A 0.0
2019-03-31 A 0.0
2019-04-30 A 2.0
2019-02-28 B 6.0
2019-03-31 B 0.0
2019-04-30 B 0.0
2019-05-31 B 5.0