查找最大化一列总和同时限制另一列总和的数据帧行的子集
Finding subset of dataframe rows that maximize one column sum while limiting sum of another
pandas 和 python 的初学者,我试图找到 select 数据框中的 10 行,以满足以下要求:
- 分类列中每个类别只有 1 个
- 最大化列的总和
- 同时将另一列的总和保持在指定阈值以下
我纠结的概念是如何同时完成所有这些。在这种情况下,目标是 select 10 行产生一个子集,其中 OPW
的总和最大化,而 salary
的总和保持不变低于整数阈值,并且 POS
中的所有字符串都是唯一的。如果它有助于理解问题,我基本上是想在预算内提出棒球梦之队,OPW
是衡量球员表现的指标,POS
是我想要的位置分配给他们。当前数据框如下所示:
playerID OPW POS salary
87 bondsba01 62.061290 OF 8541667
439 heltoto01 41.002660 1B 10600000
918 thomafr04 38.107000 1B 7000000
920 thomeji01 37.385272 1B 6337500
68 berkmla01 36.210367 1B 10250000
785 ramirma02 35.785630 OF 13050000
616 martied01 32.906884 3B 3500000
775 pujolal01 32.727629 1B 13870949
966 walkela01 30.644305 OF 6050000
354 giambja01 30.440007 1B 3103333
859 sheffga01 29.090699 OF 9916667
511 jonesch06 28.383418 3B 10833333
357 gilesbr02 28.160054 OF 7666666
31 bagweje01 27.133545 1B 6875000
282 edmonji01 23.486406 CF 4500000
0 abreubo01 23.056375 RF 9000000
392 griffke02 22.965706 OF 8019599
... ... ... ...
如果我的团队只有 3 个人,OF
、1B
和 3B
,并且我的总和salary
门槛是 19,100,000 美元,我会获得以下团队:
playerID OPW POS salary
87 bondsba01 62.061290 OF 8541667
918 thomafr04 38.107000 1B 7000000
616 martied01 32.906884 3B 3500000
理想情况下,输出将是另一个只有 10 行满足要求的数据框。我能想到的唯一解决方案是 bootstrap 一组团队(10 行),每行都有一个唯一的 POS
,删除超过 'salary' 总和阈值的团队,然后 sort_value()
团队 df.OPW.sum()
。虽然不确定如何实现。也许有更优雅的方法来做到这一点?
编辑:更改数据框以提供更多信息,添加更多上下文。
IIUC 你可以使用 groupby
聚合 sum
:
df1 = df.groupby('category', as_index=False).sum()
print (df1)
category value cost
0 A 70 2450
1 B 67 1200
2 C 82 1300
3 D 37 4500
然后按 boolean indexing
过滤 treshold
:
tresh = 3000
df1 = df1[df1.cost < tresh]
最后通过 nlargest
获得前 10 个值:
#in sample used top 3, in real data is necessary set to 10
print (df1.nlargest(3,columns=['value']))
category value cost
2 C 82 1300
0 A 70 2450
1 B 67 1200
这是一个线性规划问题。对于每个 POS,您试图最大化个人 OPW,而整个团队的总薪水受到约束。您无法通过简单的 pandas 操作来解决此问题,但可以使用 PuLP 来制定和解决它(有关示例,请参阅此处的案例研究)。
但是,您可以使用 pandas 按 POS 分组(或排序),然后 (1) 按 OPW 降序和薪水升序排序,或 (2) 添加某种 "return on investment" 列(也许是 OPW 除以薪水)并按降序排序以找到在每个位置上能给你带来最大收益的球员。
pandas 和 python 的初学者,我试图找到 select 数据框中的 10 行,以满足以下要求:
- 分类列中每个类别只有 1 个
- 最大化列的总和
- 同时将另一列的总和保持在指定阈值以下
我纠结的概念是如何同时完成所有这些。在这种情况下,目标是 select 10 行产生一个子集,其中 OPW
的总和最大化,而 salary
的总和保持不变低于整数阈值,并且 POS
中的所有字符串都是唯一的。如果它有助于理解问题,我基本上是想在预算内提出棒球梦之队,OPW
是衡量球员表现的指标,POS
是我想要的位置分配给他们。当前数据框如下所示:
playerID OPW POS salary
87 bondsba01 62.061290 OF 8541667
439 heltoto01 41.002660 1B 10600000
918 thomafr04 38.107000 1B 7000000
920 thomeji01 37.385272 1B 6337500
68 berkmla01 36.210367 1B 10250000
785 ramirma02 35.785630 OF 13050000
616 martied01 32.906884 3B 3500000
775 pujolal01 32.727629 1B 13870949
966 walkela01 30.644305 OF 6050000
354 giambja01 30.440007 1B 3103333
859 sheffga01 29.090699 OF 9916667
511 jonesch06 28.383418 3B 10833333
357 gilesbr02 28.160054 OF 7666666
31 bagweje01 27.133545 1B 6875000
282 edmonji01 23.486406 CF 4500000
0 abreubo01 23.056375 RF 9000000
392 griffke02 22.965706 OF 8019599
... ... ... ...
如果我的团队只有 3 个人,OF
、1B
和 3B
,并且我的总和salary
门槛是 19,100,000 美元,我会获得以下团队:
playerID OPW POS salary
87 bondsba01 62.061290 OF 8541667
918 thomafr04 38.107000 1B 7000000
616 martied01 32.906884 3B 3500000
理想情况下,输出将是另一个只有 10 行满足要求的数据框。我能想到的唯一解决方案是 bootstrap 一组团队(10 行),每行都有一个唯一的 POS
,删除超过 'salary' 总和阈值的团队,然后 sort_value()
团队 df.OPW.sum()
。虽然不确定如何实现。也许有更优雅的方法来做到这一点?
编辑:更改数据框以提供更多信息,添加更多上下文。
IIUC 你可以使用 groupby
聚合 sum
:
df1 = df.groupby('category', as_index=False).sum()
print (df1)
category value cost
0 A 70 2450
1 B 67 1200
2 C 82 1300
3 D 37 4500
然后按 boolean indexing
过滤 treshold
:
tresh = 3000
df1 = df1[df1.cost < tresh]
最后通过 nlargest
获得前 10 个值:
#in sample used top 3, in real data is necessary set to 10
print (df1.nlargest(3,columns=['value']))
category value cost
2 C 82 1300
0 A 70 2450
1 B 67 1200
这是一个线性规划问题。对于每个 POS,您试图最大化个人 OPW,而整个团队的总薪水受到约束。您无法通过简单的 pandas 操作来解决此问题,但可以使用 PuLP 来制定和解决它(有关示例,请参阅此处的案例研究)。
但是,您可以使用 pandas 按 POS 分组(或排序),然后 (1) 按 OPW 降序和薪水升序排序,或 (2) 添加某种 "return on investment" 列(也许是 OPW 除以薪水)并按降序排序以找到在每个位置上能给你带来最大收益的球员。