我想能够在遇到较大规模分组时,无需手动逐一写出每个iloc并采用if/elif语句的情况下重构我的函数,以实现其可扩展性。我有一个示例数据表df_stack_exchange:
data_stack_exchange = {'store': ['A','B', 'B', 'C', 'C', 'C', 'D', 'D', 'D', 'D'],
'worker': [1,1,2,1,2,3,1,2,3,4],
'boxes': [105, 90, 100, 80, 10, 200, 70, 210, 50, 0],
'optimal_boxes': [0,0,0,0,0,0,0,0,0,0]}
df_stack_exchange = pandas.DataFrame(data_stack_exchange)
| 序号 | 商店 | 工人 | 箱子 | 最优分配 |
| ---: | :--: | ---: | ---: | -------: |
| 0 | A | 1 | 105 | 0 |
| 1 | B | 1 | 90 | 0 |
| 2 | B | 2 | 100 | 0 |
| 3 | C | 1 | 80 | 0 |
| 4 | C | 2 | 10 | 0 |
| 5 | C | 3 | 200 | 0 |
| 6 | D | 1 | 70 | 0 |
| 7 | D | 2 | 210 | 0 |
| 8 | D | 3 | 50 | 0 |
| 9 | D | 4 | 0 | 0 |
工人的优先级按数值顺序排列,我希望给他们每人分配最多100个箱子,直到没有箱子可以分配为止。唯一条件是,如果有且仅有一个工人(如商店A的情况),那么即使箱子总数超过100个,这个工人也将获得所有箱子。请参见下方预期的数据框结果。
| 序号 | 商店 | 工人 | 箱子 | 最佳分配箱子数 |
| ----: | :--: | ----: | ----: | --------------: |
| 0 | A | 1 | 105 | 105 |
| 1 | B | 1 | 90 | 100 |
| 2 | B | 2 | 100 | 90 |
| 3 | C | 1 | 80 | 100 |
| 4 | C | 2 | 10 | 100 |
| 5 | C | 3 | 200 | 90 |
| 6 | D | 1 | 70 | 100 |
| 7 | D | 2 | 210 | 100 |
| 8 | D | 3 | 50 | 100 |
| 9 | D | 4 | 0 | 30 |
我编写了如下所示的函数,虽然它可以得到我想要的结果,但这种方法不可持续,因为我必须手动为每个iloc指定条件。我希望可以通过循环或其他方式重写这个函数,使其能够在不需要不断添加elif的情况下处理更大的分组规模。当前的解决方案在处理像D商店那样有10+个工人的分组时,并不具备良好的可扩展性。
def box_optimizer(x):
if x['optimal_boxes'].count() == 1:
x['optimal_boxes'].iloc[0] = x['boxes'].sum()
return x
elif x['optimal_boxes'].count() == 2:
x['optimal_boxes'].iloc[0] += numpy.where(x['boxes'].sum() - x['optimal_boxes'].sum() > 100, 100, x['boxes'].sum() - x['optimal_boxes'].sum())
x['optimal_boxes'].iloc[1] += numpy.where(x['boxes'].sum() - x['optimal_boxes'].sum() > 100, 100, x['boxes'].sum() - x['optimal_boxes'].sum())
return x
elif x['optimal_boxes'].count() == 3:
# 对于3名工人的逻辑...
return x
elif x['optimal_boxes'].count() == 4:
# 对于4名工人的逻辑...
return x
df_stack_exchange_function = pandas.DataFrame(df_stack_exchange.groupby('store', as_index=False, group_keys=False).apply(box_optimizer))
# 预期输出的数据框
df_stack_exchange_function