【问题标题】:Pandas group operation on columnsPandas 对列的分组操作
【发布时间】:2017-09-22 14:53:09
【问题描述】:

我有一个分组的 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。

最终的数据框应该是这样的:

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 

【问题讨论】:

  • 向我们展示您迄今为止所做的尝试。
  • 欢迎来到 Stack Overflow。你已经尝试过什么来做到这一点?请查看How much research effort is expected?。 Stack Overflow 不是编码服务。您应该在发布之前研究您的问题并尝试自己编写代码。如果您遇到特定的问题,请返回并附上Minimal, Complete, and Verifiable example 和您尝试过的内容的摘要,以便我们提供帮助。
  • 我只根据 dis、type 和 id 对数据框进行了分组,但我仍然坚持使用 groupbyobject。如果不应用任何聚合函数,我无法将 groupby 对象转换为数据框。早些时候,我对特定日期的数量字段求和,以获得经过的天数。但我无法弄清楚如何保持我的字段完好无损并仅添加列以获得所需的输出

标签: python pandas dataset


【解决方案1】:

我认为您需要transform 将组的大小计数为total_order,然后计算qty 中的零个数,最后通过difffillnadays 得到差异:

注意 - 对于不同的需要排序的列,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)

【讨论】:

  • 我发布的原始数据是一个 groupby 对象(不是数据框),根据 dis、type 和 id 分组。我如何根据该分组获得所需的输出?谢谢!
  • 只需将 g = df.groupby(['type','date']) 更改为 g = df.groupby(['dis','id','type','date'])
  • 我改变了答案 - 因为按这个 slumn 排序也是必要的,并且还在最后一个 groupby 中添加了列。
  • 我会试用并尽快通知您
  • 当然,我在等。我的zero_qty 栏目不同,如果不明白您的要求,请多解释。谢谢。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-03-17
  • 2021-11-07
  • 2015-05-06
  • 1970-01-01
  • 2019-06-23
  • 2021-10-31
  • 2018-11-28
相关资源
最近更新 更多