在2个ID上对Pandas中的重复项进行分组,并以不同方式转换其余列

时间:2015-10-26 15:24:54

标签: python pandas

为了这个问题,让我们假设我们在Pandas有2个商店和库存,有重复的条目。我们在条形码上标明每个项目以及它到达商店的日期(因此,如果日期不同,我们会考虑不同的项目,即使条形码相同),我们也会在每个商店中存储每个商品的库存,和价格:

      arrival_date   bar_code   stock_shop1   stock_shop2   price
1       2015-08-30    8000001            52            11     100
2       2015-08-30    8000001            48             0      85
3       2015-09-11    8000001            10            20      95
4       2015-10-04    8000002             5            10      50
5       2015-10-04    8000002            30            25      49

我们希望按到货日期和条形码分组,并且:

  1. 汇总每家商店的库存
  2. 设置最低价格(我们在销售中,我们希望在两个商店中提供相同的优惠)
  3. 所以我们应该得到:

          arrival_date   bar_code   stock_shop1   stock_shop2   price
    1       2015-08-30    8000001           100            11      85
    2       2015-09-11    8000001            10            20      95
    3       2015-10-04    8000002            35            35      49
    

    我已经看到了几个类似的问题,即使有两个ID,但我还没有发现是否可以对某些列求和并在其他列中保留最大值或最小值。我想这是可能的,我只是不知道如何。

    我试过了:

    df.join(df.groupby(['arrival_date', 'bar_code'])(['stock_shop1', 'stock_shop2']).sum(), on=['arrival_date', 'bar_code'], rsuffix='_r')
    

    只是为了检查我是否至少可以通过“到达日期”来分组。和' bar_code'和库存列相加,但我得到错误:

    TypeError: 'DataFrameGroupBy' obejct is not callable
    

    任何帮助?

2 个答案:

答案 0 :(得分:4)

是的,您可以在agg中提及您可以在每列上应用哪个聚合规则。

In [121]: (df.groupby(['arrival_date', 'bar_code'])
             .agg({'stock_shop1': np.sum, 'stock_shop2': np.sum, 'price': np.min})
           )
Out[121]:
                       price  stock_shop1  stock_shop2
arrival_date bar_code
2015-08-30   8000001      85          100           11
2015-09-11   8000001      95           10           20
2015-10-04   8000002      49           35           35

答案 1 :(得分:1)

您的代码存在的问题是,您尝试将Groupby object称为 - df.groupby(['arrival_date', 'bar_code'])(..) - 因此问题。

您也不需要使用DataFrame.join,您可以只为groupby然后.aggregate()(或.agg())执行多列。示例 -

df.groupby(['arrival_date', 'bar_code']).agg({'stock_shop1':sum,'stock_shop2':sum,'price':min})

如果您不希望将'arrival_date''bar_code'作为索引,则可以调用.reset_index()来重置索引。示例 -

df.groupby(['arrival_date', 'bar_code']).agg({'stock_shop1':sum,'stock_shop2':sum,'price':min}).reset_index()

演示 -

In [14]: df
Out[14]:
  arrival_date  bar_code  stock_shop1  stock_shop2  price
1   2015-08-30   8000001           52           11    100
2   2015-08-30   8000001           48            0     85
3   2015-09-11   8000001           10           20     95
4   2015-10-04   8000002            5           10     50
5   2015-10-04   8000002           30           25     49

In [15]: df.groupby(['arrival_date', 'bar_code']).agg({'stock_shop1':sum,'stock_shop2':sum,'price':min})
Out[15]:
                       stock_shop2  stock_shop1  price
arrival_date bar_code
2015-08-30   8000001            11          100     85
2015-09-11   8000001            20           10     95
2015-10-04   8000002            35           35     49

In [16]: df.groupby(['arrival_date', 'bar_code']).agg({'stock_shop1':sum,'stock_shop2':sum,'price':min}).reset_index()
Out[16]:
  arrival_date  bar_code  stock_shop2  stock_shop1  price
0   2015-08-30   8000001           11          100     85
1   2015-09-11   8000001           20           10     95
2   2015-10-04   8000002           35           35     49