python - Pandas 在 DataFrame 中填写缺失的每月日期,用零填充特定列
问题描述
我遇到了 Pandas 的问题,以及如何在 DataFrame 中填写缺失的日期。给定DataFrame的结构如下:
Amount Code Type Date
0 34.97 J36J 74343 2016-01-01
1 16.32 J36J 74343 2016-04-01
2 10.30 J36J 69927 2015-12-01
3 10.45 J36J 69927 2016-07-01
4 5.63 J36J 69927 2017-03-01
5 15.79 J36J 69927 2018-09-01
6 15.00 J36J 69927 2019-06-01
7 6.44 J36J 69926 2016-03-01
8 6.47 J36J 69926 2017-03-01
9 15.00 J36J 69926 2018-07-01
10 15.00 J36J 69926 2019-06-01
- 金额:嗯,金额
- Code:Productcode,在整个DataFrame中都是一样的
- Type:A Producttype,有很多不同的
- 日期:跨越 2015 年 12 月至 2020 年 9 月之间时间的日期范围。
我的目标是为涵盖此时间跨度的每种类型提供每月条目。意思是,每个材料应该有 58 个条目。“人为”创建的每月条目的数量应为 0。因此,我的预期输出将是(仅针对一种类型,例如)
Amount Code Type Date
0 34.97 J36J 74343 2016-01-01
1 16.32 J36J 74343 2016-02-01
2 0 J36J 74343 2016-03-01
3 0 J36J 74343 2016-04-01
4 0 J36J 74343 2016-05-01
5 0 J36J 74343 2016-06-01
6 0 J36J 74343 2016-07-01
7 0 J36J 74343 2016-08-01
8 0 J36J 74343 2016-09-01
9 0 J36J 74343 2016-10-01
10 0 J36J 74343 2016-11-01
11 0 J36J 74343 2016-12-01
幸运的是,有人已经有同样的问题(Pandas 在 DataFrame 中用多列填充缺失的日期)
我调整了对我的案例很有帮助的答案:
df.Date=pd.to_datetime(df.Date)
s=pd.date_range(df.Date.min(),df.Date.max(),freq='MS')
df=df.set_index(['Code','Type','Date']).\
Amount.unstack().reindex(columns=s,fill_value=0).stack().reset_index()
df
这工作得很好,但我后来检查了生成的 DataFrame,似乎有些日期丢失了。
398 74343 J36J 2016-01-01 34.97
399 74343 J36J 2016-02-01 0.00
400 74343 J36J 2016-04-01 16.32
401 74343 J36J 2016-05-01 0.00
402 74343 J36J 2016-06-01 0.00
403 74343 J36J 2016-08-01 0.00
404 74343 J36J 2016-10-01 0.00
405 74343 J36J 2016-11-01 0.00
406 74343 J36J 2016-12-01 0.00
你们中有人知道这可能是什么原因吗?我假设可能是因为我选择的频率('MS')?但我认为其他任何一个都不合适。(https://pandas.pydata.org/pandas-docs/stable/user_guide/timeseries.html)或者我必须手动设置数据范围吗?在我最初的 DataFrame 中,显然并非所有日期都可用。
对此问题的任何帮助表示赞赏。
BR
解决方案
这是一个微妙的,很有趣。
import pandas as pd
data = {'Amount' :[34.97, 16.32, 10.3, 10.45, 5.63, 15.79, 15, 6.44, 6.47, 15, 15],
'Code': ['J36J','J36J','J36J','J36J','J36J','J36J','J36J','J36J','J36J','J36J','J36J'],
'Type': [74343,74343,69927,69927,9927,69927,69927,69926,69926,69926,69926],
'Date': ['1/1/2016','4/1/2016','12/1/2015','7/1/2016','3/1/2017','9/1/2018','6/1/2019','3/1/2016','3/1/2017','7/1/2018','6/1/2019']}
df = pd.DataFrame(data)
df['Date'] = pd.to_datetime(df['Date'], format='%m/%d/%Y')
df
这得到了上述值的起点。然后弄清楚发生了什么需要一段时间,问题是我们对所有类型使用相同的 s 而不是单独使用。因此,如果日期是另一种类型,则不会被覆盖。
为了解决这个问题,我把它分成几部分,这样我们就可以把它重新组装起来。
outdf = pd.DataFrame(columns = df.columns)
s=pd.date_range(df.Date.min(),df.Date.max(),freq='MS')
for name, subdf in df.groupby('Type'):
thisdf=subdf.set_index(['Code','Type','Date']).\
Amount.unstack().reindex(columns=s,fill_value=0).stack().reset_index()
thisdf.rename(columns={0: "Amount", "level_2": "Date"}, errors="raise",inplace=True)
thisdf.reset_index(inplace=True)
thisdf = thisdf[['Code', 'Type', 'Date', 'Amount']]
outdf = pd.concat([outdf,thisdf])
outdf = outdf[['Code', 'Type', 'Date', 'Amount']]
outdf.reset_index(inplace=True)
outdf = outdf[['Code', 'Type', 'Date', 'Amount']]
所以我们所做的是将它分解成单独的项目,然后在每次通过 groupby 后将它们粘在一起。这样我们就不会错过其他类型的日期。
推荐阅读
- python - 类型错误:'collection' 对象不可调用。尝试将多个文件上传到 mlab 集合时
- react-final-form - 如何挂钩 react-final-form 更新?
- docker - 基于 docker 的应用程序的 IDE 依赖项和自动完成
- javascript - 在 React 中设置状态
- javascript - 检查未定义类型的 JSON 响应
- amazon-web-services - AWS CDK:如何从 Route53 定位 API Gateway API
- java - 使用日期对字符串 [] 进行排序
- java - 膨胀类 com.google.android.youtube.player.YouTubeThumbnailView 时出错
- javascript - Django JsonResponse 使用 JavaScript 在模板中显示而不刷新页面
- gitlab - Gitlab 跑步者不会杀死取消的工作