Python,索引和分配到Np数组

2024-10-03 06:30:22 发布

您现在位置:Python中文网/ 问答频道 /正文

为了提高速度,我想避免forloops。 我有一个图像阵列,看起来像: image = np.zeros_like(np.zeros(shape=(480,640,1)),dtype=np.uint8) 以及具有以下类型的类型化np数组Eventsdtype = [('x', '<f8'),('y', '<f8'),('grayVal','<u2') 其中“x”=图像数组的行,“y”=列

问题是: 如何将Events中的grayVal分配给image中的所有xy

到目前为止,我尝试过(而且更多内容无法显示): For循环:

for event in Events:
    image[event['y'],event['x']] = event['grayVal']

和索引

events['y'].shape
(98210,)
events['x'].shape
(98210,)
events['grayVal'].shape
(98210,)
image[np.ix_(events['y'],events['x'])] = events['grayVal']

由于出现错误消息,它无法正常工作:

ValueError: shape mismatch: value array of shape (98210,) could not be broadcast to indexing result of shape (98210,98210,1)

我错过了什么?谢谢你的帮助


Tags: of图像imageeventnpzeros数组events
2条回答

让我们来看一个小例子,一个我们可以实际检查和使用的例子

创建结构化数组:

In [32]: dt = np.dtype([('x', int),('y', int) ,('grayVal','u2')])
In [33]: events = np.zeros(5, dt)
In [34]: events['x'] = np.arange(5)
In [35]: events['y'] = np.array([3,4,0,2,1])
In [36]: events['grayVal'] = np.arange(1,6)

要检查索引,请创建一个漂亮的二维数组:

In [38]: image = np.arange(25).reshape(5,5)
In [39]: image
Out[39]: 
array([[ 0,  1,  2,  3,  4],
       [ 5,  6,  7,  8,  9],
       [10, 11, 12, 13, 14],
       [15, 16, 17, 18, 19],
       [20, 21, 22, 23, 24]])

看看ix_产生的-2数组可以相互广播。A(5,1)和(1,5),向(5,5)广播:

In [40]: np.ix_(events['y'], events['x'])
Out[40]: 
(array([[3],
        [4],
        [0],
        [2],
        [1]]),
 array([[0, 1, 2, 3, 4]]))

使用这些数组对image进行索引只是对值进行洗牌-结果仍然是一个2d数组:

In [41]: image[np.ix_(events['y'], events['x'])]
Out[41]: 
array([[15, 16, 17, 18, 19],
       [20, 21, 22, 23, 24],
       [ 0,  1,  2,  3,  4],
       [10, 11, 12, 13, 14],
       [ 5,  6,  7,  8,  9]])

如果我们改为使用数组而不是使用ix_数组进行索引:

In [42]: image[events['y'], events['x']]
Out[42]: array([15, 21,  2, 13,  9])

这只是用ix_生成的数组的对角线。使用(n,)和(n,)数组进行索引会生成一个(n,)值数组(与ix_(n,n)数组相反)

因此,从零图像开始,我们可以通过以下方式分配值:

In [43]: image= np.zeros((5,5), 'u2')
In [44]: image[events['y'], events['x']]=events['grayVal']
In [45]: image
Out[45]: 
array([[0, 0, 3, 0, 0],
       [0, 0, 0, 0, 5],
       [0, 0, 0, 4, 0],
       [1, 0, 0, 0, 0],
       [0, 2, 0, 0, 0]], dtype=uint16)

我现在只能想到一个慢版本,带有for循环。但是如果数组是稀疏的,那么这就可以了。也许其他人可以将其矢量化

import numpy as np

image =  np.zeros(shape=(3,4 ),dtype=np.uint8)  # image is empty
 
# evy is just a bag of nonzero pixels

evy=np.zeros(shape=(3), dtype = [('x', '<u2'),('y', '<u2') ,('grayVal','<u2') ])
evy[0]=(1,1,128)
evy[1]=(0,0,1)
evy[2] =(2,3,255) 
 #slow version
for i in range(3):
    image[evy[i][0],evy[i][1]]=evy[i][2]
        

输出:

array([[  1,   0,   0,   0],
       [  0, 128,   0,   0],
       [  0,   0,   0, 255]], dtype=uint8)

相关问题 更多 >