问题描述
| 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)