查找数据帧行的子集,最大化一列总和,同时限制另一列

时间:2016-10-10 05:28:45

标签: python algorithm pandas numpy data-science

pandas和python的初学者,我试图在数据框中选择10行,以满足以下要求:

  1. 分类列中每个类别中只有一个
  2. 最大化列的总和
  3. 同时保持另一列的总和低于指定的阈值
  4. 我挣扎的概念是如何同时完成所有这些。在这种情况下,目标是选择 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个人,OF1B3B,我的总和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行的数据帧。我能想到的唯一解决方案是引导一堆团队(10行),每行有一个唯一的POS,删除超过'薪水'总和阈值的团队,然后sort_value()团队df.OPW.sum()。不知道如何实现这一点。也许有更优雅的方式来做到这一点? 编辑:更改了数据框以提供更多信息,添加了更多上下文。

2 个答案:

答案 0 :(得分:1)

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 indexingtreshold

进行过滤
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

答案 1 :(得分:1)

这是线性编程问题。对于每个POS,您试图最大化个人OPW,而整个团队的总薪水受到约束。你不能用简单的pandas操作来解决这个问题,但PuLP可以用来制定和解决它(参见案例研究中的一些例子)。

但是,你可以通过使用pandas按POS(或排序)POS​​然后(1)按OPW降序和工资升序排序,或者(2)添加某种“返回”来接近手动解决方案投资“专栏(OPW除以薪水,也许),然后按下降排序,找到能给你带来每个位置最大收益的球员。