在 Python 中添加数量为 0 的缺失日期

时间:2021-07-28 21:47:39

标签: python pandas dataframe date time-series

我有一个数据框,其中包含来自不同位置的多个不同项目编号。问题是我缺少所有不同组合的日期。因此,例如对于第 1 项,我想要所有位置都缺少的所有日期。在数据集中不存在的日子里,为每个位置的每个项目添加数量为 0 的日期的最佳方法是什么?请和谢谢!

enter image description here

我尝试了以下

df.set_index(data["DATE", "ITEMNUMBER"], inplace=True)

df = data.resample('D').sum().fillna(0)

这给了我以下错误 - ValueError: Length mismatch: Expected 1 rows, received array of length 749629

所以我尝试了以下 -

df.set_index(data["DATE", "ITEMNUMBER"], inplace=True)

df = data.resample('D').sum().fillna(0)

如果容差不是无,则会导致关键错误:

2 个答案:

答案 0 :(得分:0)

要获得 DATEITEMNUMBERLOCATION 的所有组合,您可以尝试:

import itertools
df2 = df.set_index(["DATE", "ITEMNUMBER", "LOCATION"])
df2 = df2.reindex(itertools.product(df['DATE'].unique(),
                                    df['ITEMNUMBER'].unique(),
                                    df['LOCATION'].unique())
                 ).fillna(0).reset_index()
df2

示例输入:

         DATE  ITEMNUMBER LOCATION  QUANTITY
0  2021-07-28           1        A         0
1  2021-07-28           2        B         1
2  2021-07-28           1        B         2
3  2021-07-29           1        A         3
4  2021-07-30           2        A         4

输出:

          DATE  ITEMNUMBER LOCATION  QUANTITY
0   2021-07-28           1        A       0.0
1   2021-07-28           1        B       2.0
2   2021-07-28           2        A       0.0
3   2021-07-28           2        B       1.0
4   2021-07-29           1        A       3.0
5   2021-07-29           1        B       0.0
6   2021-07-29           2        A       0.0
7   2021-07-29           2        B       0.0
8   2021-07-30           1        A       0.0
9   2021-07-30           1        B       0.0
10  2021-07-30           2        A       4.0
11  2021-07-30           2        B       0.0

答案 1 :(得分:0)

使用玩具数据框:

>>> df = pd.DataFrame([{'date': '2014-07-14', 'id': 1, 'q': 1}, {'date': '2014-07-15', 'id': 1, 'q': 1}, {'date': '2014-07-17', 'id': 1, 'q': 1}, {'date': '2014-07-18', 'id': 1, 'q': 2}, {'date': '2014-07-14', 'id': 5, 'q': 2}])
>>> df
         date  id  q
0  2014-07-14   1  1
1  2014-07-15   1  1
2  2014-07-17   1  1
3  2014-07-18   1  2
4  2014-07-14   5  2

我将日期转换为日期时间,然后在每个 ID 内,在索引最小值和最大值之间重新索引,创建空行。然后我用 0 为 q 填充数量列 np.nan 并向前填充剩余的空值。

>>> df.assign(date=lambda df: pd.to_datetime(df['date'])) \
    .set_index('date').groupby('id') \
    .apply(lambda df: df.reindex(pd.date_range(df.index.min(), df.index.max(), freq='D'))) \
    .assign(q=lambda df: df['q'].fillna(0)). \
    .groupby(level=0).ffill()
                id    q
id                     
1  2014-07-14  1.0  1.0
   2014-07-15  1.0  1.0
   2014-07-16  1.0  0.0
   2014-07-17  1.0  1.0
   2014-07-18  1.0  2.0
5  2014-07-14  5.0  2.0

我不确定您想如何处理位置列。通过完全删除该列,我的回答得到了简化。

如果您自己不知道,不要在最后ffill。相反,分组依据并将 ffill 仅 ID 列的一个分配回 ID,将位置保留为 nan