Pandas组操作列

时间:2017-09-21 06:47:37

标签: python pandas dataset

我有一个分组的pandas groupby对象。

dis type id  date         qty
1   1    10  2017-01-01   1
1   1    10  2017-01-01   0
1   1    10  2017-01-02   4.5
1   2    11  2017-04-03   1
1   2    11  2017-04-03   2
1   2    11  2017-04-03   0
1   2    11  2017-04-05   0

我想在这个groupby对象上应用一些操作。

  1. 我想添加一个新列total_order,用于计算特定材料特定日期的订单数量
  2. 列zero_qty,用于计算特定物料的特定日期的零订单数
  3. 更改日期列,使其计算特定材料的每个后续订单之间的天数。第一个订单变为0。
  4. 最终的数据框应该是这样的:

    dis type id date  qty  total_order  zero_qty
    1   1    10  0    1    2            1
    1   1    10  0    0    2            1
    1   1    10  1    4.5  1            1
    1   2    11  0    1    3            2
    1   2    11  0    2    3            2 
    1   2    11  0    0    3            2
    1   2    11  2    0    1            1 
    

1 个答案:

答案 0 :(得分:1)

我认为您需要将transform的小组数量计为total_order,然后计算qty中的零数,最后通过diff计算fillna }和days

注意 - 对于差异需要排序的列,sort_values必要时执行:

df = df.sort_values(['dis','type','id','date'])

g = df.groupby(['dis','type','id','date'])
df['total_order'] = g['id'].transform('size')
df['zero_qty'] = g['qty'].transform(lambda x: (x == 0).sum()).astype(int)
df['date'] =  df.groupby(['dis','type','id'])['date'].diff().fillna(0).dt.days
print (df)
   dis  type  id  date  qty  total_order  zero_qty
0    1     1  10     0  1.0            2         1
1    1     1  10     0  0.0            2         1
2    1     1  10     1  4.5            1         0
3    1     2  11     0  1.0            3         1
4    1     2  11     0  2.0            3         1
5    1     2  11     0  0.0            3         1
6    1     2  11     2  0.0            1         1

使用自定义函数的多个transform使用apply的另一个解决方案:

df = df.sort_values(['dis','type','id','date'])

def f(x):
    x['total_order'] = len(x)
    x['zero_qty'] =    x['qty'].eq(0).sum().astype(int)
    return x

df = df.groupby(['dis','type','id','date']).apply(f)

df['date'] =  df.groupby(['dis','type','id'])['date'].diff().fillna(0).dt.days
print (df)
   dis  type  id  date  qty  total_order  zero_qty
0    1     1  10     0  1.0            2         1
1    1     1  10     0  0.0            2         1
2    1     1  10     1  4.5            1         0
3    1     2  11     0  1.0            3         1
4    1     2  11     0  2.0            3         1
5    1     2  11     0  0.0            3         1
6    1     2  11     2  0.0            1         1

编辑:

如果需要处理更多列,最后一行也可以重写:

def f2(x):
    #add another code 
    x['date'] = x['date'].diff().fillna(0).dt.days
    return x

df = df.groupby(['dis','type','id']).apply(f2)