【问题标题】:Pandas: Calculate diff column grouped by date and additional column熊猫:计算按日期和附加列分组的差异列
【发布时间】:2022-01-11 08:22:00
【问题描述】:

我有 3 列的 Pandas DataFrame:

df = pd.DataFrame({'product__sku': [1, 1, 1, 1, 2, 2],
                   'date': ['2021-10-01 20:48:12+00:00','2021-10-31 20:48:26+00:00',
                            '2021-09-01 20:48:12+00:00','2021-09-30 20:48:26+00:00',
                            '2021-10-01 12:23:17+00:00','2021-10-31 12:23:17+00:00'],
                   'qty': [100, 84, 5, 10, 15, 48]})

看起来像:

|product__sku | date                      |  qty |
|1            | 2021-10-01 20:48:12+00:00 |  100 |
|1            | 2021-10-31 20:48:26+00:00 |  84  |
|1            | 2021-09-01 20:48:12+00:00 |  5   |
|1            | 2021-09-30 20:48:26+00:00 |  10  |
|2            | 2021-10-01 12:23:17+00:00 |  15  |
|2            | 2021-10-31 12:23:17+00:00 |  48  |

我需要按两列日期(月份)和 product__sku 分组。在 group_by I 列 'qty' 应通过公式 max_date qty - min_date qty 减去(差异)

我希望看到的结果

|product__sku | date                      | diff |
|1            | 2021-09-30 20:48:12+00:00 |  5   |
|1            | 2021-10-31 20:48:12+00:00 |  -16 |
|2            | 2021-10-31 20:48:26+00:00 |  33  |

我尝试使用石斑鱼

        dg = df.groupby([ pd.Grouper('product__sku'), pd.Grouper(key='date', freq='1M')])['qty'].diff().fillna(0)

但是得到了不同的结果:

|0     0.0
| 1   -16.0
| 2     0.0
Name: qty, dtype: float64

【问题讨论】:

  • 性能对您的解决方案很重要?
  • 是的,我们在后端使用 django,所以我的查询集可能包含数千条记录
  • 好的,所以尝试这两种解决方案并更快地选择。

标签: python pandas dataframe pandas-groupby


【解决方案1】:

第一组由product__skumonth 组成。然后定义一个自定义函数来查找每个组中最大和最小日期之间的qty 差异并将其应用于每个组:

def func(x):
    dates = x['date'].sort_values()
    diff = x.loc[dates.index[-1], 'qty'] - x.loc[dates.index[0], 'qty']
    x = x[x['date']==dates.iloc[-1]]
    x['diff'] = diff
    return x[['product__sku','date','diff']]
    

df['date'] = pd.to_datetime(df['date'])
df = df.assign(month=df['date'].dt.month).groupby(['product__sku','month']).apply(func).reset_index(drop=True)

输出:

   product__sku                      date  diff
0             1 2021-09-30 20:48:26+00:00     5
1             1 2021-10-31 20:48:26+00:00   -16
2             2 2021-10-31 12:23:17+00:00    33

【讨论】:

    【解决方案2】:

    使用GroupBy.aggfirst 并在排序后的DataFrame 中最后,因此获取最小和最大日期的值,最后使用DataFrame.pop 减去值以删除列first, last

    如果每个组需要最后一个dates,也可以为date 列使用命名聚合:

    df['date'] = pd.to_datetime(df['date'])
    
    dg = (df.sort_values(['product__sku','date'])
            .groupby(['product__sku', pd.Grouper(key='date', freq='1M')])
            .agg(first=('qty','first'),last=('qty','last'), date=('date', 'first'))
            .reset_index(level=-1, drop=True)
            .reset_index()
            )
    dg['diff'] = dg.pop('last').sub(dg.pop('first'))
    print (dg)
       product__sku                      date  diff
    0             1 2021-09-01 20:48:12+00:00     5
    1             1 2021-10-01 20:48:12+00:00   -16
    2             2 2021-10-01 12:23:17+00:00    33
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-05-07
      • 2019-11-03
      • 2021-01-05
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多