Pandas 为缺失的日期填零 *由 * 组定义
Posted
技术标签:
【中文标题】Pandas 为缺失的日期填零 *由 * 组定义【英文标题】:Pandas fill-in-zero for by missing dates *defined by* group 【发布时间】:2020-01-26 05:05:06 【问题描述】:问题:使用 pandas - 如何有效地用零值填充缺失的日期,每月(例如最后一天索引)频率,相对于最小/最大日期值 per 组?
编辑不假定输入日期对应于其月份的最后一天。 要解决此问题,请在以下建议的答案中添加以下行:
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
上述链接的答案似乎与每个组无关,而是与整个数据集的最小/最大日期值有关。
【问题讨论】:
【参考方案1】:一个快速修复:
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
【讨论】:
似乎使用“interpolate”有时会(在大型数据集上)导致最终输出具有所有 NA——将“interpolate”更改为“max”似乎可以解决这个问题。 为了安全地使用“resample('M')”,添加以下行:df.date = df.date + pd.offsets.MonthEnd(0)【参考方案2】:我会使用groupby
、resample
和asfreq
(编辑:当你在非月末日期更新问题时。我按照你的建议添加了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
【讨论】:
为了安全地使用“resample('M')”,添加以下行:df.date = df.date + pd.offsets.MonthEnd(0) @Quetzalcoatl:啊,我明白你的意思了。您想处理df.date
中的某些值不是月末日期的异常情况 :)
@Quetzalcoatl:我添加了pd.offsets.MonthEnd
,因为您建议完成答案:)
@AndyL.:您如何为每个组添加相同的日期范围?我的意思是每个组都有相同的范围(即 2020 年 1 月到 2020 年 12 月)。你会怎么做?以上是关于Pandas 为缺失的日期填零 *由 * 组定义的主要内容,如果未能解决你的问题,请参考以下文章
将 pandas 列转换为 datetime64,包括缺失值
pandas使用reindex函数为日期索引中有缺失日期的dataframe进行索引重置(所有日期都连续)并使用fill_value参数为行进行默认填充
pandas使用read_csv函数读取文件并解析日期数据列(parse dates)pandas使用read_csv函数读取文件并将缺失值转化为空字符串