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

Adding Missing Dates with 0 in Quantity in Python

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

我尝试了以下方法

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

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

这给了我以下错误 - ValueError:长度不匹配:预期 1 行,接收到长度为 749629 的数组

所以我尝试了以下 -

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

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

如果公差不是 None:

,则会导致密钥错误

要获得 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

使用玩具数据框:

>>> 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。相反,分组并仅将 ID 列的 ffill 分配回 ID,将位置保留为 nan.