如何迭代每个组的列值并跟踪总和
How to iterate over column values for each group and track sum
我有 4 个数据框,如下所示
df_raw = pd.DataFrame(
{'stud_id' : [101, 101,101],
'prod_id':[12,13,16],
'total_qty':[100,1000,80],
'ques_date' : ['13/11/2020', '10/1/2018','11/11/2017']})
df_accu = pd.DataFrame(
{'stud_id' : [101,101,101],
'prod_id':[12,13,16],
'accu_qty':[10,500,10],
'accu_date' : ['13/08/2021','02/11/2019','17/12/2018']})
df_inv = pd.DataFrame(
{'stud_id' : [101,101,101],
'prod_id':[12,13,18],
'inv_qty':[5,100,15],
'inv_date' : ['16/02/2022', '22/11/2020','19/10/2019']})
df_bkl = pd.DataFrame(
{'stud_id' : [101,101,101,101],
'prod_id' :[12,12,12,17],
'bkl_qty' :[15,40,2,10],
'bkl_date':['16/01/2022', '22/10/2021','09/10/2020','25/06/2020']})
我的objective是找出下面的
a) 获取阈值超过 50% 的日期
阈值由以下公式给出
threshold = (((df_inv['inv_qty']+df_bkl['bkl_qty']+df_accu['accu_qty'])/df_raw['total_qty'])*100)
我们必须按相同的顺序添加。意思是,首先,我们必须添加 inv_qty
,然后添加 bkl_qty
,最后添加 accu_qty
。我们这样做是为了在它们超过总数量的 50% 时识别正确的日期。此外,必须为每个 stud_id
和 prod_id
.
计算
但问题是 df_bkl
对同一个 stud_id
和 prod_id
有多个记录,这是设计使然。真实数据也是这样的。而 df_accu
和 df_inv
每个 stud_id
和 prod_id
.
将只有一行
在上面的公式中df['bkl_qty'],we have to use each value of df['bkl_qty']
计算和
例如:让我们取 stud_id = 101
和 prod_id = 12
。
他的total_qty = 100
,inv_qty = 5
,他的accu_qty=10
。但他有三个 bkl_qty
值 - 15,40 和 2。因此,必须以如下方式计算阈值
5(inv_qty的值)+15(bkl_qty的第一个值)+40(bkl_qty的第二个值)+2(bkl_qty的第三个值=73=]) +10(是 accu_qty 的值)
所以,现在有了上面的,我们可以知道他的阈值在他的bkl_qty
值为40时超过了50%。意思是,5+15+40 = 60(大于50%的total_qty (100)).
我正在尝试类似下面的操作
df_stage_1 = df_raw.merge(df_inv,on=['stud_id','prod_id'], how='left').fillna(0)
df_stage_2 = df_stage_1.merge(df_bkl,on=['stud_id','prod_id'])
df_stage_3 = df_stage_2.merge(df_accu,on=['stud_id','prod_id'])
df_stage_3['threshold'] = ((df_stage_3['inv_qty'] + df_stage_3['bkl_qty'] + df_stage_3['accu_qty'])/df_stage_3['total_qty'])*100
但这是不正确的,因为我无法通过 df_bkl
中 bkl_qty
的值来计算每个值
在这个 post 中,我只显示了一个 stud_id=101
的样本数据,但实际上我有超过 1000 个 stud_id
和 prod_id
。
因此,任何优雅高效的方法都是有用的。我们必须将此逻辑应用于百万记录数据集。
我希望我的输出如下所示。每当总和值超过 total_qty 的 50% 时,我们需要获取相应的日期
stud_id,prod_id,total_qty,threshold,threshold_date
101 12 100 72 22/10/2021
可以用groupby
和cumsum
做累加求和
# add cumulative sum column to df_bkl
df_bkl['csum'] = df_bkl.groupby(['stud_id','prod_id'])['bkl_qty'].cumsum()
# use df_bkl['csum'] to compute threshold instead of bkl_qty
df_stage_3['threshold'] = ((df_stage_3['inv_qty'] + df_stage_3['csum'] + df_stage_3['accu_qty'])/df_stage_3['total_qty'])*100
# check if inv_qty already exceeds threshold
df_stage_3.loc[df_stage_3.inv_qty > df_stage_3.total_qty/2, 'bkl_date'] = df_stage_3['inv_date']
# next doing some filter and merge to arrive at the desired df
gt_thres = df_stage_3[df_stage_3['threshold'] > df_stage_3['total_qty']/2]
df_f1 = gt_thres.groupby(['stud_id','prod_id','total_qty'])['threshold'].min().to_frame(name='threshold').reset_index()
df_f2 = gt_thres.groupby(['stud_id','prod_id','total_qty'])['threshold'].max().to_frame(name='threshold_max').reset_index()
df = pd.merge(df_f1, df_stage_3, on=['stud_id','prod_id','total_qty','threshold'], how='inner')
df2 = pd.merge(df,df_f2, on=['stud_id','prod_id','total_qty'], how='inner')
df2 = df2[['stud_id','prod_id','total_qty','threshold','bkl_date']].rename(columns={'threshold_max':'threshold', 'bkl_date':'threshold_date'})
print(df2)
提供输出为:
stud_id prod_id total_qty threshold threshold_date
0 101 12 100 72.0 22/10/2021
这个有用吗?
我有 4 个数据框,如下所示
df_raw = pd.DataFrame(
{'stud_id' : [101, 101,101],
'prod_id':[12,13,16],
'total_qty':[100,1000,80],
'ques_date' : ['13/11/2020', '10/1/2018','11/11/2017']})
df_accu = pd.DataFrame(
{'stud_id' : [101,101,101],
'prod_id':[12,13,16],
'accu_qty':[10,500,10],
'accu_date' : ['13/08/2021','02/11/2019','17/12/2018']})
df_inv = pd.DataFrame(
{'stud_id' : [101,101,101],
'prod_id':[12,13,18],
'inv_qty':[5,100,15],
'inv_date' : ['16/02/2022', '22/11/2020','19/10/2019']})
df_bkl = pd.DataFrame(
{'stud_id' : [101,101,101,101],
'prod_id' :[12,12,12,17],
'bkl_qty' :[15,40,2,10],
'bkl_date':['16/01/2022', '22/10/2021','09/10/2020','25/06/2020']})
我的objective是找出下面的
a) 获取阈值超过 50% 的日期
阈值由以下公式给出
threshold = (((df_inv['inv_qty']+df_bkl['bkl_qty']+df_accu['accu_qty'])/df_raw['total_qty'])*100)
我们必须按相同的顺序添加。意思是,首先,我们必须添加 inv_qty
,然后添加 bkl_qty
,最后添加 accu_qty
。我们这样做是为了在它们超过总数量的 50% 时识别正确的日期。此外,必须为每个 stud_id
和 prod_id
.
但问题是 df_bkl
对同一个 stud_id
和 prod_id
有多个记录,这是设计使然。真实数据也是这样的。而 df_accu
和 df_inv
每个 stud_id
和 prod_id
.
在上面的公式中df['bkl_qty'],we have to use each value of df['bkl_qty']
计算和
例如:让我们取 stud_id = 101
和 prod_id = 12
。
他的total_qty = 100
,inv_qty = 5
,他的accu_qty=10
。但他有三个 bkl_qty
值 - 15,40 和 2。因此,必须以如下方式计算阈值
5(inv_qty的值)+15(bkl_qty的第一个值)+40(bkl_qty的第二个值)+2(bkl_qty的第三个值=73=]) +10(是 accu_qty 的值)
所以,现在有了上面的,我们可以知道他的阈值在他的bkl_qty
值为40时超过了50%。意思是,5+15+40 = 60(大于50%的total_qty (100)).
我正在尝试类似下面的操作
df_stage_1 = df_raw.merge(df_inv,on=['stud_id','prod_id'], how='left').fillna(0)
df_stage_2 = df_stage_1.merge(df_bkl,on=['stud_id','prod_id'])
df_stage_3 = df_stage_2.merge(df_accu,on=['stud_id','prod_id'])
df_stage_3['threshold'] = ((df_stage_3['inv_qty'] + df_stage_3['bkl_qty'] + df_stage_3['accu_qty'])/df_stage_3['total_qty'])*100
但这是不正确的,因为我无法通过 df_bkl
bkl_qty
的值来计算每个值
在这个 post 中,我只显示了一个 stud_id=101
的样本数据,但实际上我有超过 1000 个 stud_id
和 prod_id
。
因此,任何优雅高效的方法都是有用的。我们必须将此逻辑应用于百万记录数据集。
我希望我的输出如下所示。每当总和值超过 total_qty 的 50% 时,我们需要获取相应的日期
stud_id,prod_id,total_qty,threshold,threshold_date
101 12 100 72 22/10/2021
可以用groupby
和cumsum
做累加求和
# add cumulative sum column to df_bkl
df_bkl['csum'] = df_bkl.groupby(['stud_id','prod_id'])['bkl_qty'].cumsum()
# use df_bkl['csum'] to compute threshold instead of bkl_qty
df_stage_3['threshold'] = ((df_stage_3['inv_qty'] + df_stage_3['csum'] + df_stage_3['accu_qty'])/df_stage_3['total_qty'])*100
# check if inv_qty already exceeds threshold
df_stage_3.loc[df_stage_3.inv_qty > df_stage_3.total_qty/2, 'bkl_date'] = df_stage_3['inv_date']
# next doing some filter and merge to arrive at the desired df
gt_thres = df_stage_3[df_stage_3['threshold'] > df_stage_3['total_qty']/2]
df_f1 = gt_thres.groupby(['stud_id','prod_id','total_qty'])['threshold'].min().to_frame(name='threshold').reset_index()
df_f2 = gt_thres.groupby(['stud_id','prod_id','total_qty'])['threshold'].max().to_frame(name='threshold_max').reset_index()
df = pd.merge(df_f1, df_stage_3, on=['stud_id','prod_id','total_qty','threshold'], how='inner')
df2 = pd.merge(df,df_f2, on=['stud_id','prod_id','total_qty'], how='inner')
df2 = df2[['stud_id','prod_id','total_qty','threshold','bkl_date']].rename(columns={'threshold_max':'threshold', 'bkl_date':'threshold_date'})
print(df2)
提供输出为:
stud_id prod_id total_qty threshold threshold_date
0 101 12 100 72.0 22/10/2021
这个有用吗?