列总和接近N的最小行数,处理非整数

问题描述

我有一个在Pandas中看起来像这样的DataFrame。

|  clip_id |   duration |
|---------:|-----------:|
|     0050 |    3.085   |
|     0019 |    3.125   |
|     0001 |    3.265   |
...
|     0010 |    4.47    |
|     0024 |    4.48    |
|     0034 |    4.49    |
|     0004 |    4.515   |
...
|     0008 |    6.795   |
|     0034 |    6.99    |
|     0026 |    6.995   |
...
|     0004 |    9.005   |
|     0024 |    9.185   |
|     0048 |    9.265   |
|     0029 |   10.055   |
|     0001 |   10.255   |
|     0006 |   10.85    |

在这里使用省略号修剪了表格,但是行数通常在30到100之间。而且我已经使用duration列对表格进行了排序。

我的目标是找到剪辑的最小数量,以使它们的总和滞后于某个值 N 。换句话说,如果 N = 25,那么选择底部的三行是不够好的解决方案,因为总和为31.16,并且存在一个更接近25的greedier / lazier解。

自从我上了算法/数据结构课程以来已经过去了很长时间,但是我确定有一个与堆有关的解决方案可以解决这个问题。我之前也没有用Python进行动态编程,但是也许有一个涉及DP的解决方案。环顾StackOverflow上的其他已解决问题,获得最多投票的答案始终假定为

(A)您正在处理整数,或

(B)您将能够找到确切的金额

但是我要尝试的情况并非如此。理想情况下,如果我可以在将数据存储在Pandas DataFrame中的同时执行此操作,则可以很容易地为这些结果行返回clip_id值。

感谢我在这方面可以获得的所有帮助!

编辑:因此,要更多地考虑问题,很难解决的是两个相互竞争的目标:我想要的行数最少,但我也希望总和不超过 N (如果可能)。因此,在两个目标之间,我要说更接近 N 是更重要的条件。因此,例如,如果将行数增加2可使总数更接近> = N,那么将是更可取的。

解决方法

该解决方案是否在您想要的下方?您是否要获得多于N的行或要排除它们?根据您的回答,我可以更新代码。

def min_num_rows(data,threshold):
   for i in range(1,len(data)):
      if data[-i:]['duration'].sum() > threshold:
         data = data[: -i]
         break
      else:
         continue
   return data[-i: ]
df = df.sort_values('duration',ascending = True)
above = min_num_rows(df,25)