2013-04-18 43 views
3

我写了一个小脚本,通过了解他们的行和列值分配到numpy的阵列列分配坐标:行,没有for循环

gridarray = np.zeros([3,3]) 
gridarray_counts = np.zeros([3,3]) 

cols = np.random.random_integers(0,2,15) 
rows = np.random.random_integers(0,2,15) 
data = np.random.random_integers(0,9,15) 

for nn in np.arange(len(data)): 
    gridarray[rows[nn],cols[nn]] += data[nn] 
    gridarray_counts[rows[nn],cols[nn]] += 1 

其实,后来我才知道有多少值存储在同一个网格单元格以及它们的总和。但是,对100000+以上的长度数组执行此操作会变得非常慢。有没有使用for循环的另一种方法?

是一种方法类似,这可能吗?我知道这还没有工作。

gridarray[rows,cols] += data 
gridarray_counts[rows,cols] += 1 
+0

只是为了向未来的读者阐明,看起来很简单的解决方案,声明不起作用,确实不起作用,因为'行,列'包含重复的索引。有关更多详细信息,请参阅[此问题](http://stackoverflow.com/questions/16034672/how-do-numpys-in-place-operations-e-g-work)。 – shx2

回答

2

我会用bincount这一点,但现在bincount只需要1darrays所以你需要编写自己的ndbincout,是这样的:

def ndbincount(x, weights=None, shape=None): 
    if shape is None: 
     shape = x.max(1) + 1 

    x = np.ravel_multi_index(x, shape) 
    out = np.bincount(x, weights, minlength=np.prod(shape)) 
    out.shape = shape 
    return out 

然后,你可以这样做:

gridarray = np.zeros([3,3]) 

cols = np.random.random_integers(0,2,15) 
rows = np.random.random_integers(0,2,15) 
data = np.random.random_integers(0,9,15) 

x = np.vstack([rows, cols]) 
temp = ndbincount(x, data, gridarray.shape) 
gridarray = gridarray + temp 
gridarray_counts = ndbincount(x, shape=gridarray.shape) 
+0

完美工作,比for循环分配方法快10倍。 – HyperCube

0

您可以直接做到这一点:

gridarray[(rows,cols)]+=data 
gridarray_counts[(rows,cols)]+=1 
+0

不幸的是,这不会导致相同的(正确)的输出。 – HyperCube

+0

@HyperCube啊好的,我假设了唯一的索引。我会保留这个答案,以防其他人可能有独特的指标。 – Bitwise