一. 特定区域赋值操作
最近任务需要,对一个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