我正在做以下事情。
import numpy as np
import pylab
.....
x = np.zeros([250,200])
for tup in tups:
x[tup[1],tup[0]] = x[tup[1],tup[0]] + 1
pylab.imshow(x)
哪里
tups = [(x1,y1),(x2,y2),....]
和xi
,yi
是整数
这适用于积分较少的tup
。对于大量的点~10 ^ 6,需要几个小时。
你能想到更快的方法吗?
答案 0 :(得分:1)
我可以很容易地看到一个小改进,而不是下一个:
for tup in tups:
x[tup[1],tup[0]] = x[tup[1],tup[0]] + 1
尝试做
for tup in tups:
x[tup[1],tup[0]] += 1
由于这会覆盖相同的内存地址,而不是创建一个新的内存点来放置'旧值+ 1'(注意:在这种情况下,这可能只会导致边际加速,但是如果你这样做的话技巧A + = B而不是C = A + B,在A和B分别是Gb的numpy ndarrays的情况下,它实际上是一个巨大的加速)
为什么你读作元组的东西?难道你不应该首先尝试将其作为一个numpy ndarray读取,而不是将其作为元组列表读取而不是更改为numpy数组?你在哪里创建那个庞大的元组列表?如果可以避免这种情况,那么只是避免使用元组列表而不是创建它而不是后来交换到一个numpy解决方案会更好吗?
编辑:所以我只是想知道你可以通过+ =得到这个加速,同时问为什么你有一个很大的元组列表,但这太长了,不能把两件事都放在评论中< / p>
另一个问题:我是否正确假设您的元组可以有多个重复?喜欢
tups = [(1,0), (2,4), (1,0), (1,2), ..., (999, 999), (992, 999)]
这样在你的结果中,除了0和1之外还会存在其他值吗?或者是你的结果数组中只存在1和0的东西?
答案 1 :(得分:1)
使用numpy,您可以将您的索引对转换为平面索引并对其进行bincount:
import numpy as np
import random
rows, cols = 250, 200
n = 1000
tups = [(random.randint(0, rows-1),
random.randint(0, cols-1)) for _ in range(n)]
x = np.zeros((rows, cols))
for tup in tups:
x[tup[0],tup[1]] += 1
flat_idx = np.ravel_multi_index(zip(*tups), (rows, cols))
y = np.bincount(flat_idx, minlength=rows*cols).reshape(rows, cols)
np.testing.assert_equal(x, y)
它将比任何循环解决方案快得多。