Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/308.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/sorting/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/date/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python—在2D列表中选择总计为累积总和68%的元素_Python_Sorting - Fatal编程技术网

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

Python—在2D列表中选择总计为累积总和68%的元素,python,sorting,Python,Sorting,我在二维列表中有我的值 a = [[5,2],[7,4],[0,3]] 多亏了这个问题的答案 我设法按降序对它们进行排序,得到了上一个列表中的值的坐标 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)

我在二维列表中有我的值

a = [[5,2],[7,4],[0,3]]
多亏了这个问题的答案 我设法按降序对它们进行排序,得到了上一个列表中的值的坐标

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)
然后,我需要开始对有序元素求和,直到它们达到某个值,即累积总和的68%。在这种情况下,这意味着执行以下逻辑操作:

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

2) 累计金额的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)
极限计算可以写成

lim = 0.68 * total
但是,如果您的数据保证是整数,那么将
lim
也作为一个整数就更整洁了,因为比较两个整数要比比较一个整数和一个浮点稍微高效一些。当您执行将int与float(包括比较)组合的操作时,必须将它们转换为公共类型才能执行该操作


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


谢谢。幸运的是,我的数据不是整数,实际上它们是非常小的数字,因此我不应该使用lim作为整数。我如何提取这些坐标对,我的意思是如何安排代码,使其自动存储[1][0]和[0][0](如示例所示,但通常所有占总数68%的值)在一个新列表中?@johnhenry您可以使用与我们将坐标保存到
所选
列表中相同的方法来执行此操作。在循环外部初始化空列表,例如
values=[]
。然后在循环中执行
值。在选定的
行之前或之后追加(v)
。追加(t)
行。谢谢,尽管我的问题有点复杂。实际上,我必须绘制与网格上的坐标相关联的值a[1][0]和a[0][0]。您的解决方案输出的元组给我带来了困难,因为我无法再次使用它们来选择要发送到的数组元素plotting@johnhenry对不起,我不太明白这个问题。如果您有一个坐标元组,例如
t=(2,1)
您可以执行
a[t[0]][t[1]]
来获得
a[2][1]
。但是,如果创建我前面的评论中描述的
列表,则不需要这样做,因为该列表中的每个项都对应于
所选
列表中的坐标元组。另一个选项是修改我的答案中的代码,这样它就可以在
b
数组中找到对应于所选组件末尾的索引。我将添加更多代码来解释我的意思。
lim = 0.68 * total
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