用熊猫标记分组数据集中的最后一组行

时间:2018-09-06 20:37:48

标签: python pandas

编辑:鉴于以下建议的df.assign(Flag=1 - df.duplicated(['id', 'quarter', 'lot'], keep='last'))方法,以下问题

 index   mkid     ordernumber quarter lotnumber1 order_xldate  Flag
441670  10176228  0108595504  2015Q2    12947-1   2015-04-09     0
441211  10176228  0108663905  2015Q2    12947-1   2015-04-29     1
450008  10176228  0108663905  2015Q2     129161   2015-04-29     1
440268  10176228  0108779992  2015Q2    12987-1   2015-05-29     0
448187  10176228  0108779992  2015Q2    12848-1   2015-05-29     1
439085  10176228  0108895691  2015Q2    12987-1   2015-06-29     1
446123  10176228  0108895691  2015Q2    12965-1   2015-06-29     1
419419  10176228  0109003405  2015Q3    12969-1   2015-07-27     1
429893  10176228  0109003405  2015Q3    12987-1   2015-07-27     1
426850  10176228  0109241988  2015Q3      13929   2015-09-15     1
384762  10176228  0109385611  2015Q4     K10127   2015-10-09     1

Flag字段将应用于给定季度中的每个ordernumber不是 最后 ordernumber。因此,在上面,对于2015Q2Flag应该只对ordernumber 0108895691的两行都命中


以前的帖子

我目前有一个销售订单数据集,其中每个ordernumber被分为很多批次(即lot1lot2等)。因此,每个ordernumber可能有不同的行。其他相关列是帐户idquarter(即2018年第二季度)。对于每个给定id中的每个给定quarter,我想使用Pandas / Python将标志应用于给定季度中最后一个订单的全部 all 。有什么建议吗?

当前拥有:

masterDF['FLAG'] = masterDF.groupby(by=['id','quarter'],as_index=False)['ordernumber'].nth(-1)
masterDF['LAST_ORDER_OF_QUARTER'] = np.where(masterDF['FLAG'].isnull(),0,1)

但是,这只会在该ID /季度/订单组合的最后行上放置1,而不是在给定订单内的所有行上显示(如果该序号出现在多于一行。

我想要的输出是orderB的两个批次上都为1

id   |   quarter   |   ordernumber   |   lot      |    Last Order of Quarter
----------------------------------------------------------------------------
A    |   2018Q1    |   orderA        |   lot1     |     0
A    |   2018Q1    |   orderB        |   lot1     |     1
A    |   2018Q1    |   orderB        |   lot2     |     1

代替:

id   |   quarter   |   ordernumber   |   lot      |    Last Order of Quarter
----------------------------------------------------------------------------
A    |   2018Q1    |   orderA        |   lot1     |     0
A    |   2018Q1    |   orderB        |   lot1     |     0
A    |   2018Q1    |   orderB        |   lot2     |     1

有什么建议吗?

2 个答案:

答案 0 :(得分:2)

使用duplicated

df.assign(Flag=1 - df.duplicated(['id', 'quarter', 'lot'], keep='last'))

  id quarter ordernumber   lot  Flag
0  A  2018Q1      orderA  lot1     0
1  A  2018Q1      orderB  lot1     1
2  A  2018Q1      orderB  lot2     1

同一件事

df.assign(**{'Last Order': 1 - df.duplicated(['id', 'quarter', 'lot'], keep='last')})

  id quarter ordernumber   lot  Last Order
0  A  2018Q1      orderA  lot1           0
1  A  2018Q1      orderB  lot1           1
2  A  2018Q1      orderB  lot2           1

答案 1 :(得分:0)

您的groupby对象提供了一个方便的表,可以将其合并回主表。在该表上将“ Last Order”分配为1,将其合并到main,然后用0填充NaN。

new = df.groupby(['id', 'quarter']).nth(-1)
del new['lot']
new['Last Order'] = 1
df = pd.merge(df, new, how='left').fillna(0)

这给出了:

    id  quarter ordernumber lot value
0   a   2018Q1  orderA  lot1    0.0
1   a   2018Q1  orderA  lot2    0.0
2   a   2018Q1  orderB  lot1    1.0
3   b   2018Q1  orderC  lot2    0.0
4   b   2018Q1  orderD  lot1    1.0
5   b   2018Q1  orderD  lot2    1.0