Python - 选择总和为 2D 列表中累积总和的 68% 的元素

标签 python sorting

我的值在一个二维列表中。

a = [[5,2],[7,4],[0,3]]

感谢这个问题的回答 sorting list of lists and getting indices in unsorted list 我设法按降序对它们进行排序,并获得了前一个列表中值的坐标。

from operator import itemgetter

b = [((i, j), v) for i, t in enumerate(a) for j, v in enumerate(t)]
b.sort(key=itemgetter(-1), reverse=True)
print(b)
coords, vals = zip(*b)
print(vals)
print(coords)

输出:

[((1, 0), 7), ((0, 0), 5), ((1, 1), 4), ((2, 1), 3), ((0, 1), 2), ((2, 0), 0)]
(7, 5, 4, 3, 2, 0)
((1, 0), (0, 0), (1, 1), (2, 1), (0, 1), (2, 0))

现在我需要首先计算元素的总累计和,我使用

cumulative_sum = np.cumsum(a)

然后我需要开始对有序元素求和,直到它们达到某个值,即 cumulative_sum 的 68%。在这种情况下,这意味着执行以下逻辑操作:

1) 累积总和 = 5+2+7+4+0+3 = 21

2) cumulative_sum 的 68% = 14.28

3) 然后开始求和:7+5+4+... 并选择相关元素,直到它们超过 14.28(在这个简化的示例中,这将只选择值 7 和 5)

4) 在选中的元素中,我需要获取数组a中的坐标 (在这种情况下,(1,0)(0,0) )

最佳答案

使用一个简单的 for 循环来遍历 b 中的(坐标,值)对,这很容易完成。诀窍是在我们将坐标元组 t 添加到 selected 中的坐标列表之前, 测试总和是否会溢出所需的限制。

from operator import itemgetter

a = [[5,2],[7,4],[0,3]]

b = [((i, j), v) for i, t in enumerate(a) for j, v in enumerate(t)]
b.sort(key=itemgetter(-1), reverse=True)
coords, vals = zip(*b)

total = sum(vals)
lim = int(0.68 * total)

selected = []
s = 0
for t, v in b:
    if s + v <= lim:
        s += v
        selected.append(t)
    else:
        break

print(s, selected)

输出

12 [(1, 0), (0, 0)]

极限计算可以写成

lim = 0.68 * total

但是如果您的数据保证是整数,那么将 lim 也作为整数会更整洁,因为比较 2 个整数比比较整数和 float 稍微更有效。当您执行结合 int 和 float 的操作(包括比较)时,必须将它们转换为通用类型才能执行操作。


这是一个替代版本,如评论中所讨论的那样。它循环遍历 vals 中的值,直到达到所需的总和,同时跟踪 vals 中的索引。然后它使用该索引将使用的值和相应的坐标元组从 b 列表切入新的 selected 列表(这与 selected 以前版本的列表)。

from operator import itemgetter

a = [[5, 2], [7, 4], [0, 3]]

b = [((i, j), v) for i, t in enumerate(a) for j, v in enumerate(t)]
b.sort(key=itemgetter(-1), reverse=True)
coords, vals = zip(*b)

lim = 0.68 * sum(vals)

s = 0
for i, v in enumerate(vals):
    if s + v <= lim:
        s += v
    else:
        break

selected = b[:i]
print(i, selected)

for (i, j), v in selected:
    print(i, j, v)

输出

2 [((1, 0), 7), ((0, 0), 5)]
1 0 7
0 0 5

关于Python - 选择总和为 2D 列表中累积总和的 68% 的元素,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40359938/

相关文章:

python - 在 Django Admin 中,选项可以依赖于其他值吗?

ruby - 先按值排序散列,然后按键排序

c++ - 如何根据不寻常数字的数量对数组进行排序

根据导数或指数级别对 Mathematica 中的公式进行排序

php - 如何使用 PHP 根据嵌套命名空间数组中的值对数组进行排序

c - 冒泡排序——输出整数的字符串

python - 暂时抑制 PyQt 事件?

python - Tensorflow GPU 在使用 Python 2.7 的 multiprocessing.Process 调用 fork 的新进程中不可用

python - Tensorflow Visual Studio 导入错误

python - Pandas 拆解专栏