2014-01-30 83 views
0

我在做以下事情。Python:从元组列表创建图像的快速方法

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),....] 

xiyi是整数

这是罚款tup具有低数量的点。对于大量的点〜10^6,它需要数小时。

你能想到一个更快的方法吗?

+0

“对于大量的点~10^6 ...” - 你的意思是1000 * 1000的图片?它真的需要几个小时吗? – zhangxaochen

+0

不,我的意思是有10^6或更高元组的tups。我想我可能会遇到另一个让它放慢速度的问题。 –

+0

@ medPhys-pl这可能会有所帮助:[增加Numpy多重数组与重复索引](http://stackoverflow.com/questions/7433142/increment-numpy-multi-d-array-with-repeated-indices) –

回答

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 

因为这将覆盖相同的内存ADRESS,而不是创建一个新的内存现货(注意:在这种情况下,这可能只会导致边际加速,但如果您使用相同的技巧A + = B而不是C = A + B,在A和B为一个Gb的numpy ndarrays每个左右,它实际上是一个巨大的加速)

为什么你阅读元组的东西?你是不是应该首先阅读它作为一个numpy的ndarray,而不是将它作为一个元组列表读取,而不是改变为一个numpy数组?你在哪里创建元组列表?如果可以避免这种情况,那么避免使用元组列表会更好,而不是创建它,并且以后再交换到一个numpy解决方案?

编辑:所以我只想告诉你这个加速,你可以通过+ =得到,同时问你为什么有一个大的元组列表,但是这太长了,以至于无法将这两个东西放在评论中

另一个问题:我是否正确地假设你的元组可以有多个重复?像

tups = [(1,0), (2,4), (1,0), (1,2), ..., (999, 999), (992, 999)] 

因此,在您的endresult,其他值比0和1将存在?或者是你的结果数组只存在一个和零的数组?

+0

是的,你对重复是正确的。 –

+0

@ medPhys-pl如果你不首先创建一个元组列表,那么它会快得多,所以如果你显示你创建元组列表的位置,那么它也可以在那里得到改进(如果直接创建成一个numpy数组,而不是先使用元组列表,然后去一个numpy数组) – usethedeathstar

+0

我已经处理了元组,并且用一个numpy数组卡住了。虽然速度并不快。我会实施Jaime的建议,并比较 –

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) 

这将是比任何循环解决方案快得多。