pandas 如何从另一个 Dataframe 获取适当的类别-一对多匹配

cvxl0en2  于 2023-03-11  发布在  其他
关注(0)|答案(1)|浏览(183)

我们有两台机器,每台机器生产不一致的数量df1是它的 Dataframe

df1 = pd.DataFrame({'machine':['A','A','A','A','A','B','B','B','B','B','B'],'qty':[1,3,5,2,4,2,4,5,5,3,2]})

[

]

df2是箱式卷大小的 Dataframe ,也是每个卷大小不同

df2 = pd.DataFrame({'machine':['A','A','A','A','A','B','B','B','B','B','B','B'],
                    'box_id':['box_1','box_2','box_3','box_4','box_5','box_6','box_7','box_8','box_9','box_10','box_11','box_12'],
                    'volume':[4,5,3,2,5,3,4,3,6,4,8,5]})

[

]
我想将“box_id”列添加到df1中,以查找并匹配df2**的适当box id。如底部的输出 Dataframe 。

output_df = pd.DataFrame({'machine':['A','A','A','A','A','B','B','B','B','B','B'],
                           'qty':[1,3,5,2,4,2,4,5,5,3,2],
                           'box_id':['box_1','box_1','box_2','box_3','box_5','box_6','box_7','box_9','box_11','box_12','box_12']})

[

]
详细解释
按从上到下的顺序添加box_id接近每个箱体积(df2)但不超过每个箱
例如,在机器A中,第一个产品数量为1,但第一个 Package 箱(box_1)体积为4 box_1可以容纳第一个产品,第一列中的 Package 箱ID为box_1
则第二产品数量为3,box_1具有第一产品(数量1),但该 Package 盒中有3个可用空间第二行中的 Package 盒ID也是box_1第三个产品是5,也是下一个 Package 盒(box_2)卷为5,因此第三行为box_2第四个产品为2,下一个框(box_3)volume为3,因此第三行为box_3但在第五种情况下,product为4,但下一个框(box_4)仅为2,因此不能使用box_4,必须使用下面的box_5当机器更改时,再次重置该框并使用下一个框。
在机器B中,第一个产品数量是2,但下一个箱(box_6)体积是3,因此可以使用box_6
不是为了学习,实际上我们工厂是这样生产的,我就用这个做部分自动化
我希望能得到Maven的大力帮助

2eafrhcq

2eafrhcq1#

你可以用一种更直接的方式来做,简单地一行一行地迭代df1,然后把每一个项目放在存储在列表中的盒子里,但是我想探索如何更有效地做这件事,特别是当盒子很大,可以容纳大量的项目时。
所以,我们开始吧。
您可以先向df1添加一个累积和列。

df1['cum_sum'] = df1.groupby('machine').cumsum()

然后你可以遍历df2中的盒子,把df1中尽可能多的物品放进盒子,然后移到下一个盒子。如果盒子里没有物品,你就不放任何东西,然后移到下一个盒子。你可以跟踪已经放好的物品的累计数量,这样你就可以只寻找还没有放好的物品。

for machine, df in df2.groupby('machine'):
      cum_volume_placed = 0
      for indx, row in df.iterrows():
        applicable_rows = df1['machine'] == machine  # all items in this machine
        applicable_rows &= df1['cum_sum'] > cum_volume_placed  # which are after whatever we already placed
        applicable_rows &= df1['cum_sum'] <= cum_volume_placed + row.volume  # which fits within current box
        if sum(applicable_rows) > 0:
          df1.loc[applicable_rows, 'box_id'] = row.box_id
          cum_volume_placed = df1.loc[applicable_rows, 'cum_sum'].iloc[-1]

相关问题