我有一个Nx3
numpy数组:
A = [[01,02,03]
[11,12,13]
[21,22,23]]
如果第二个和第三个数字的总和大于20,我需要一个交换第二和第三列的数组:
[[01,02,03]
[11,13,12]
[21,23,22]]
是否有可能在没有循环的情况下实现这一目标?
更新
所以,这背后的故事是我想在RGB图像中交换颜色,即绿色和蓝色,但不是黄色 - 这是我的条件。根据经验,我发现它是abs(green - blue) > 15 && (blue > green)
swapped = np.array(img).reshape(img.shape[0] * img.shape[1], img.shape[2])
idx = ((np.abs(swapped[:,1] - swapped[:,2]) < 15) & (swapped[:, 2] < swapped[:, 1]))
swapped[idx, 1], swapped[idx, 2] = swapped[idx, 2], swapped[idx, 1]
plt.imshow(swapped.reshape(img.shape[0], img.shape[1], img.shape[2]))
这实际上有效,但部分有效。第一列将被交换,但第二列将被覆盖。
# tested in pyton3
a = np.array([[1,2,3],[11,12,13],[21,22,23]])
a[:,1], a[:,2] = a[:,2], a[:,1]
array([[ 1, 3, 3],
[11, 13, 13],
[21, 23, 23]])
答案 0 :(得分:3)
这是masking
-
# Get 1D mask of length same as the column length of array and with True
# values at places where the combined sum is > 20
m = A[:,1] + A[:,2] > 20
# Get the masked elements off the second column
tmp = A[m,2]
# Assign into the masked places in the third col from the
# corresponding masked places in second col.
# Note that this won't change `tmp` because `tmp` isn't a view into
# the third col, but holds a separate memory space
A[m,2] = A[m,1]
# Finally assign into the second col from tmp
A[m,1] = tmp
示例运行 -
In [538]: A
Out[538]:
array([[ 1, 2, 3],
[11, 12, 13],
[21, 22, 23]])
In [539]: m = A[:,1] + A[:,2] > 20
...: tmp = A[m,2]
...: A[m,2] = A[m,1]
...: A[m,1] = tmp
In [540]: A
Out[540]:
array([[ 1, 2, 3],
[11, 13, 12],
[21, 23, 22]])
答案 1 :(得分:2)
如何使用np.where
以及&#34; fancy&#34;索引,并np.flip
交换元素。
In [145]: A
Out[145]:
array([[ 1, 2, 3],
[11, 12, 13],
[21, 22, 23]])
# extract matching sub-array
In [146]: matches = A[np.where(np.sum(A[:, 1:], axis=1) > 20)]
In [147]: matches
Out[147]:
array([[11, 12, 13],
[21, 22, 23]])
# swap elements and update the original array using "boolean" indexing
In [148]: A[np.where(np.sum(A[:, 1:], axis=1) > 20)] = np.hstack((matches[:, :1], np.flip(matches[:, 1:], axis=1)))
In [149]: A
Out[149]:
array([[ 1, 2, 3],
[11, 13, 12],
[21, 23, 22]])
基于@Divakar's suggestion的另一种方法是:
首先获取指定条件的非零指数(此处为 <第二列和第三列中的元素的总和> 20)
In [70]: idx = np.flatnonzero(np.sum(A[:, 1:3], axis=1) > 20)
然后使用np.ix_
In [71]: gidx = np.ix_(idx,[1,2])
# finally update the original array `A`
In [72]: A[gidx] = A[gidx][:,::-1]