python - 调整日期列(填补日期空白并更新至特定日期)

标签 python pandas datetime dask

我有以下情况:

显示每个产品和商店的每次库存变动(买入/卖出)的数据框。

        date     sku     store  Units   balance
0 2019-10-01  103993.0    001    0.0     10.0
1 2019-10-02  103993.0    001    1.0      9.0
2 2019-10-04  103993.0    001    1.0      8.0
3 2019-10-05  103993.0    001    0.0      8.0
4 2019-10-01  103994.0    002    0.0     12.0
5 2019-10-02  103994.0    002    1.0     11.0
6 2019-10-04  103994.0    002    1.0     10.0
7 2019-10-05  103994.0    002    0.0     10.0

假设今天是 2019 年 10 月 8 日,更新此日期的最佳方式是什么:

  • 填补空白(例如添加 2019-01-03 行)
  • 将每个(SKU 和商店)更新为今天的日期:
    • 保留“存储和余额”列的最后一个值
    • 在“单位”列中插入 0(这意味着这些天我没有售出单位)

所以输出应该是这样的:

           date     sku     store  Units   balance
    0 2019-10-01  103993.0    001    0.0     10.0
    1 2019-10-02  103993.0    001    1.0      9.0
    2 2019-10-03  103993.0    001    0.0      9.0
    3 2019-10-04  103993.0    001    1.0      8.0
    4 2019-10-05  103993.0    001    0.0      8.0
    5 2019-10-06  103993.0    001    0.0      8.0
    6 2019-10-07  103993.0    001    0.0      8.0
    7 2019-10-08  103993.0    001    0.0      8.0
    8 2019-10-01  103994.0    002    0.0     12.0
    9 2019-10-02  103994.0    002    1.0     11.0
   10 2019-10-03  103994.0    002    0.0     11.0
   11 2019-10-04  103994.0    002    1.0     10.0
   12 2019-10-05  103994.0    002    0.0     10.0
   13 2019-10-06  103994.0    002    0.0     10.0
   14 2019-10-07  103994.0    002    0.0     10.0
   15 2019-10-08  103994.0    002    0.0     10.0

我发现做到这一点的唯一方法是:

    dfs = []
    for _, d in df.groupby(['sku', 'store']):

        start_date = d.date.iloc[0]
        end_date = pd.Timestamp('2019-10-08')

        d.set_index('date', inplace=True)
        d = d.reindex(pd.date_range(start_date, end_date))
        dfs.append(d)

    df = pd.concat(dfs)
    df[['units']] = df[['units']].fillna(0)
    df.ffill(inplace=True)

但是这段代码没有很好地矢量化。有没有更好的方法来获得相同的结果?

最佳答案

IIUC,你可以这样做:

# min date
min_date = df.date.min()

# create a new index
new_idx = pd.MultiIndex.from_product((df.sku.unique(),
                                      pd.date_range(min_date, '2019-10-08', freq='D')),
                                     names=['sku','date']
                                    )

# reindex
new_df = df.set_index(['sku','date']).reindex(new_idx)

# fillna
new_df.Units = new_df.Units.fillna(0)

# ffill by group and dropna for invalid dates
new_df = new_df.groupby(level=0).ffill().dropna()

输出:

                     store  Units  balance
sku      date                             
103993.0 2019-09-30    1.0    0.0     10.0
         2019-10-01    1.0    0.0     10.0
         2019-10-02    1.0    1.0      9.0
         2019-10-03    1.0    0.0      9.0
         2019-10-04    1.0    1.0      8.0
         2019-10-05    1.0    0.0      8.0
         2019-10-06    1.0    0.0      8.0
         2019-10-07    1.0    0.0      8.0
         2019-10-08    1.0    0.0      8.0
103994.0 2019-10-01    2.0    0.0     12.0
         2019-10-02    2.0    1.0     11.0
         2019-10-03    2.0    0.0     11.0
         2019-10-04    2.0    1.0     10.0
         2019-10-05    2.0    0.0     10.0
         2019-10-06    2.0    0.0     10.0
         2019-10-07    2.0    0.0     10.0
         2019-10-08    2.0    0.0     10.0

注意:如果不同 SKU 的最短日期差异很大且距离今天很远,则此方法的成本可能会很高。

关于python - 调整日期列(填补日期空白并更新至特定日期),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58293185/

相关文章:

python - MultiIndex 列 DataFrame 的成对差异

php - 在 php 中使用日期 ('Y-m-d' ) 时如何正确设置给出的时间?

python - 在 python 中计算嵌套总和

python - 如何使棉花糖在序列化时引发 AttributeErrors

python - Django上传excel文件,用pandas处理,下载为csv

python - 如何在 seaborn lmplot 上添加标题?

java - 从 Hijri 日期到 Java 中的 Gregorian

python:模块中的日期时间总是提供第一次调用的日期

python - 如何使用 re.sub 将标签添加到 python 中的某些字符串?

python - 如何在 shapefile (arcmap) 的属性表中将 'ß' 替换为 'ss'? ASCII 错误