将数组索引插入到转置数组中



假设我有数组:

[[2,1,5,2], 
[1,4,2,1],
[4,5,5,7],
[1,5,9,3]]

我正在尝试将数组转置为 shape (16, 3(,其中结果数组中的前两个元素是索引号,最后一个是值。 例如:

[[0, 0, 2], [1, 0, 1], [2, 0, 5], [3, 0, 2], [0, 1, 4], ....]

这可以通过 numpy 函数或类似功能来实现吗?还是我必须用我自己的功能来做到这一点?

工作示例代码:

import numpy as np
src = np.array([[2,1,5,2],
[1,4,2,1],
[4,5,5,7],
[1,5,9,3]])
dst = np.array([])

for x in range(src.shape[0]):
for y in range(src.shape[1]):
dst = np.append(dst, [[y, x, src[x][y]]])
print(dst.reshape(16,3))

我不知道numpy 中是否有一个函数,但您可以使用列表推导来轻松构建该数组:

import numpy as np
src = np.array([[2,1,5,2],
[1,4,2,1],
[4,5,5,7],
[1,5,9,3]])
dst = np.array([ [y, x, src[x][y]] 
for x in range(src.shape[0]) 
for y in range(src.shape[1])])
print(dst.reshape(16,3))

希望这能有所帮助。

更新:有一个 numpy 函数

您可以使用numpy.ndenumerate

dst = np.array([[*reversed(x), y] for x, y in np.ndenumerate(src)])
print(dst)
#[[0 0 2]
# [1 0 1]
# [2 0 5]
# [3 0 2]
# [0 1 1]
# [1 1 4]
# [2 1 2]
# [3 1 1]
# [0 2 4]
# [1 2 5]
# [2 2 5]
# [3 2 7]
# [0 3 1]
# [1 3 5]
# [2 3 9]
# [3 3 3]]

ndenumerate将返回一个迭代器,生成数组坐标和值对。您首先需要反转所需输出的坐标。接下来,将坐标解压缩到带有值的列表1中,并使用列表推导式来使用迭代器。


原始答案

您可以尝试:

dst = np.column_stack(zip(*[*reversed(np.indices(src.shape)), src])).T
print(dst)
#[[0 0 2]
# [1 0 1]
# [2 0 5]
# [3 0 2]
# [0 1 1]
# [1 1 4]
# [2 1 2]
# [3 1 1]
# [0 2 4]
# [1 2 5]
# [2 2 5]
# [3 2 7]
# [0 3 1]
# [1 3 5]
# [2 3 9]
# [3 3 3]]

解释

首先,使用numpy.indices获取一个表示形状为src的网格索引的数组。

print(np.indices(src.shape))
#[[[0 0 0 0]
#  [1 1 1 1]
#  [2 2 2 2]
#  [3 3 3 3]]
#
# [[0 1 2 3]
#  [0 1 2 3]
#  [0 1 2 3]
#  [0 1 2 3]]]

我们可以反转这些(因为这是您希望在最终输出中的顺序(,并将解压缩到也包含src的列表1中。

然后zip此列表的所有元素以获取(col, row, val)三元组。我们可以使用numpy.column_stack.

list(zip(*[*reversed(np.indices(src.shape)), src]))
#[(array([0, 1, 2, 3]), array([0, 0, 0, 0]), array([2, 1, 5, 2])),
# (array([0, 1, 2, 3]), array([1, 1, 1, 1]), array([1, 4, 2, 1])),
# (array([0, 1, 2, 3]), array([2, 2, 2, 2]), array([4, 5, 5, 7])),
# (array([0, 1, 2, 3]), array([3, 3, 3, 3]), array([1, 5, 9, 3]))]

最后转置(numpy.ndarray.T(得到最终输出。

注释

  1. 解压缩到list中仅在python 3.5+中可用

最新更新