如何有效地将数组广播到数组

时间:2018-10-22 07:19:12

标签: python numpy

我需要用一个numpy数组构造一个图像。每个像素应基于数组中的整数获得r,g,b,alpha值。为此,我编写了以下代码:

让r是一个整数,该数组的整数范围为-2到0

print(r)
array([[-1, -1, -1, ...,  0,  0,  0],
   [-1, -1, -1, ...,  0,  0,  0],
   [-1, -1, -1, ...,  0,  0,  0],
   ...,
   [ 0,  0,  0, ...,  0,  0,  0],
   [ 0,  0,  0, ...,  0,  0,  0],
   [ 0,  0,  0, ...,  0,  0,  0]], dtype=int32)

colors是一个编码r,g,b,alpha值的字典

print(colors) 
{-2: ['0', '0', '0', '0'],
-1: ['1', '1', '1', '0.5'],
0: ['0', '0', '0', '0.5']}

获取尺寸为a.shape [0],a.shape [1],4的图像

    r = r.astype('int32')
    im = r.reshape(r.shape[0]*r.shape[1])
    im = [ colors[j]  for j in im ]
    im = np.reshape(im, (r.shape[0], r.shape[1], 4))
    im = im.astype('float64')
    toimage(im, cmin = 0, cmax = 1 ).save(dir_to + '/' + 'label' + '/' + str(zoom) + '/' + str(x) + '/' + str(y) + '.png')

此代码可以正常工作,但对于仅256 x 256的图像,运行时间已超过0.2秒。有没有人建议如何优化它?

不幸的是,numpy数组不允许我将数组广播到条目中。

2 个答案:

答案 0 :(得分:1)

这是一种方法-

v = np.array(list(colors.values()), dtype=float)
k = np.array(list(colors.keys()), dtype=int)

sidx = k.argsort()
out = v[sidx[k.searchsorted(r,sorter=sidx)]]

对于该特定字典,r以降序排列,范围从-20,我们可以避免使用searchsorted,从而替换了最后两个(实际上也可以跳过像这样的k)步骤-

out = v[-r]

对于许多用于索引的重复索引,在性能上使用np.take可能更好。例如。对于给定的样本-

In [195]: r = np.random.randint(-2,1,(400,500))

In [196]: %timeit v[-r]
100 loops, best of 3: 3.06 ms per loop

In [197]: %timeit np.take(v,-r,axis=0)
1000 loops, best of 3: 1.45 ms per loop

答案 1 :(得分:0)

这执行起来快很多,但是还是间接的...

    r = r.astype('int32')
    im = np.zeros((256,256,4))
    for i in [0,1,2,3]:
        for key in colors.keys():
            im[r == key,i] = colors[key][i]

    im = im.astype('float64')
     toimage(im, cmin = 0, cmax = 1 ).save(dir_to + '/' + 'label' + '/' + str(zoom) + '/' + str(x) + '/' + str(y) + '.png')