numpy优化用法合集(updating)

一. 特定区域赋值操作

最近任务需要,对一个superpixel 矩阵(各区域内值相同,区域间不同)进行二值化处理,根据需要对其中某些编号的像素块赋值 1,其它为 0。发现对于一张 255*255的图片,使用np.where()

new_array = np.zeros(segments.shape, dtype=np.float32)
temp_arr = np.where(segments == No, 1., 0.)
new_array += temp_arr(此处的1不会有像素重复)

的速度比遍历快近四倍!

函数 numpy.where 是三元表达式 x if condition else y 的矢量化版本。

假如我们有一个布尔数组和两个值数组:

In [140]: xarr = np.array([1.1, 1.2, 1.3, 1.4, 1.5])
In [141]: yarr = np.array([2.1, 2.2, 2.3, 2.4, 2.5])
In [142]: cond = np.array([True, False, True, True, False])

假如我们想要当对应的 cond 值为 True 时,从 xarr 中获取一个值,否则从yarr 中获取值。使用列表推到来做这件事,可能会像这样:

In [143]: result = [(x if c else y)
   .....: for x, y, c in zip(xarr, yarr, cond)]
In [144]: result
Out[144]: [1.1000000000000001, 2.2000000000000002, 1.3, 1.3999999999999999, 2.5]

这样做会有许多问题。首先,对于大的数组,它不会很快(因为所有的工作都是有纯Python来做的)。其次,对于多维数组,它不能工作。使用 np.where 你可以像这样非常简洁的编写:

In [145]: result = np.where(cond, xarr, yarr)
In [146]: result
Out[146]: array([ 1.1, 2.2, 1.3, 1.4, 2.5])

np.where 的第一个和第二个参数不需要是数组;它们中的一个或两个可以是纯量。 在数据分析中 where 的典型使用是生成一个新的数组,其值基于另一个数组。

ref:http://blog.csdn.net/baoqian1993/article/details/51786095

二. 对一个数组在其部分索引集合进行求和

numpy 的np.sum()函数基本可以满足多数情况下的要求,但是我现在需要求一个数组在其部分索引集合上的和,我目前还没发现有现成的 API 可供调用。起初选择对索引集合进行遍历求和,发现性能难以容忍,不得不手动优化,得到以下代码:

segments = slic(img_as_float(img), n_segments = 200, sigma = 5) #segments是一个二维数组

indexs = np.argwhere(segments == i)

arr_ = segments[indexs[:,0], indexs[:,1]]#注意:此处如果不对索引集合作切片处理会报错 IndexError: index × is out of bounds,原因见下文
 total_ = np.mean(arr_)

原因:

>>a = np.arange(12).reshape(3,4)
>>a
array([[ 0, 1, 2, 3],
       [ 4, 5, 6, 7],
       [ 8, 9, 10, 11]])

>>a[0,0]
0

>>a[[0,0]]  #注意,多个[]
array([[0, 1, 2, 3],
       [0, 1, 2, 3]])

a[0,0] 很好理解,不解释。a[[0,0]]有些费神,它是把整个[0,0] 作为单索引的集合作为输入,返回的必定是相同shape 的其中各个单索引的值的集合,此处就是返回 [a[0], a[0]] ,而 a[0] 就是 [ 0, 1, 2, 3] 啦~所以 a[[0,0]]  —>  [[0, 1, 2, 3],
[0, 1, 2, 3]]

ref:https://docs.scipy.org/doc/numpy/user/quickstart.html#indexing-with-arrays-of-indices

 

Share this to:

发表评论

电子邮件地址不会被公开。 必填项已用*标注