替换2D numpy数组中的值



我有以下2D numpay数组:

matrix = np.array([
[ 0,  1,  4,  3],
[ 1,  2,  5,  4],
[ 3,  4,  7,  6],
[ 4,  5,  8,  7],
[ 2, 10, 13,  5],
[10, 11, 14, 13],
[ 5, 13, 16,  8],
[13, 14, 17, 16],
[18, 19, 22, 21],
[19, 11, 10, 22],
[21, 22,  1,  0],
[22, 10,  2,  1]])

我有另一个数组,它包含我想要替换的矩阵中的值。

substitutes = np.array([ 0,  1,  2,  3,  4,  5,  6,  7,  8, 10, 11, 13, 14, 16, 17, 18, 19, 21, 22])

查找矩阵中每个替换项的索引(可能多次出现):

indices = [np.argwhere(s == matrix) for s in substitutes]

然后我做:

matrix_renumbered = copy.deepcopy(matrix)
for i, indices_per_value in enumerate(indices):
for index in indices_per_value:
# the substitutes are replaced just by the counter i (to be contiguous)
matrix_renumbered[index[0], index[1]] = i

预期结果:

array([[ 0,  1,  4,  3],
[ 1,  2,  5,  4],
[ 3,  4,  7,  6],
[ 4,  5,  8,  7],
[ 2,  9, 11,  5],
[ 9, 10, 12, 11],
[ 5, 11, 13,  8],
[11, 12, 14, 13],
[15, 16, 18, 17],
[16, 10,  9, 18],
[17, 18,  1,  0],
[18,  9,  2,  1]])

是否有更好的方法(例如使用numpy)来做双for循环所做的事情?

安迪

您可以通过利用高级索引来删除内部for循环:

for value, adv_idx in enumerate(tuple(zip(*i)) for i in indices):
matrix_renumbered[adv_idx] = value

输出:

array([[ 0,  1,  4,  3],
[ 1,  2,  5,  4],
[ 3,  4,  7,  6],
[ 4,  5,  8,  7],
[ 2,  9, 11,  5],
[ 9, 10, 12, 11],
[ 5, 11, 13,  8],
[11, 12, 14, 13],
[15, 16, 18, 17],
[16, 10,  9, 18],
[17, 18,  1,  0],
[18,  9,  2,  1]])

高级索引允许您传入行坐标列表和列坐标列表,并访问数组的这些元素:

In [1]: x = np.random.randint(0, 9, (5, 5))
In [2]: x
Out[2]:
array([[1, 2, 4, 0, 5],
[1, 5, 7, 4, 3],
[1, 3, 6, 8, 0],
[6, 3, 7, 6, 3],
[4, 3, 6, 8, 6]])
In [3]: x[[1, 2, 3], [0, 0, 0]] = 999
In [4]: x
Out[4]:
array([[  1,   2,   4,   0,   5],
[999,   5,   7,   4,   3],
[999,   3,   6,   8,   0],
[999,   3,   7,   6,   3],
[  4,   3,   6,   8,   6]])

在这里,您使用高级索引x[[1, 2, 3], [0, 0, 0]]获取第1、2和3行以及第0、0和0列。

你唯一需要改变的是你的索引数组,你需要zip()坐标成两个单独的列表,一个为行值和另一个列值(而不是(row, col)对的序列),这是通过以下方式实现的:

tuple(zip(*idx)) for idx in indices

最新更新