numpy 将二维数组的值移动/平移特定的量(向上)

zpgglvta  于 2022-11-24  发布在  其他
关注(0)|答案(1)|浏览(170)

我想了解各种二维数组转换方法。
我有一个方法可以返回对应于二维数组中应删除的值的(x,y)坐标索引。下面的值应取代要删除的值,而下面的值应移到它们的位置,依此类推。在数组的底部,将随机生成新值(此处不需要帮助,并且超出范围),在下面的示例输出中用r表示。
简单示例输入:

coordinates = [
    (0, 1), (1, 1), (2, 1)
]
test = numpy.array([
    [0, 3, 0, 4, 0, 1, 3],
    [1, 1, 1, 0, 0, 4, 1],
    [2, 3, 3, 4, 1, 4, 3],
    [3, 1, 1, 3, 3, 2, 2],
    [2, 1, 3, 4, 3, 4, 4],
    [0, 0, 1, 1, 0, 2, 0],
    [0, 1, 0, 2, 3, 4, 2],
    [3, 2, 1, 1, 3, 2, 1],
])

简单示例输出:

numpy.array([
    [0, 3, 0, 4, 0, 1, 3],
    [2, 3, 3, 0, 0, 4, 1],
    [3, 1, 1, 4, 1, 4, 3],
    [2, 1, 3, 3, 3, 2, 2],
    [0, 0, 1, 4, 3, 4, 4],
    [0, 1, 0, 1, 0, 2, 0],
    [3, 2, 1, 2, 3, 4, 2],
    [r, r, r, 1, 3, 2, 1],
])

复杂示例输入:

coordinates = [
    (1, 2), (2, 2), (3, 0), (3, 1), (3, 2), (3, 3),
    (3, 4), (4, 2), (4, 3), (4, 4), (5, 2), (6, 2),
]
test = numpy.array([
    [0, 3, 0, 4, 1, 1, 3],
    [4, 1, 0, 4, 2, 4, 1],
    [2, 4, 4, 4, 3, 3, 3],
    [3, 1, 1, 4, 3, 2, 2],
    [2, 1, 3, 4, 3, 4, 4],
    [0, 0, 1, 1, 0, 2, 0],
    [0, 1, 0, 2, 3, 4, 2],
    [3, 2, 1, 1, 3, 2, 1],
])

复杂示例输出:

numpy.array([
    [0, 3, 0, 1, 1, 1, 3],
    [4, 1, 0, 2, 2, 4, 1],
    [2, 1, 1, 1, 0, 2, 2],
    [3, 1, 3, r, 3, 4, 4],
    [2, 0, 1, r, 3, 2, 0],
    [0, 1, 0, r, r, 4, 2],
    [0, 2, 1, r, r, 2, 1],
    [3, r, r, r, r, r, r],
])

欢迎各种解决方案,简单和高效的首选,示例性的答案赞赏!
注入来自上述示例的coordinatestest变量;

import numpy

NUM_ROWS = len(test)
NUM_COLS = len(test[0])

for row_i in range(NUM_ROWS - 1, 0 - 1, -1):  # reverse loop rows (B -> T)
    for col_i in range(NUM_COLS):
        if (col_i, row_i) in coordinates:
            for lower_row_i in range(row_i + 1, NUM_ROWS):
                test[lower_row_i - 1][col_i] = test[lower_row_i][col_i]
            test[NUM_ROWS - 1][col_i] = numpy.random.randint(5)

print(test)

创建所需的输出,但必须有许多其他更干净、更有效、更简单等的方法来实现这一点。

gajydyqb

gajydyqb1#

  • 注意:您使用的坐标是反转的。如果您使用(col,row),则数字索引将是(row,col)。下面的解决方案使用转置来适应您的坐标。*

我会创建一个布尔掩码来标识要删除/移位的位置。然后使用argsortTrue值推到末尾,并使用这些索引对原始数组重新排序。

m = np.zeros_like(test, dtype=bool).T
m[tuple(zip(*coordinates))] = True

out = np.take_along_axis(test, np.argsort(m).T, axis=0)

输出量:

array([[0, 3, 0, 1, 1, 1, 3],
       [4, 1, 0, 2, 2, 4, 1],
       [2, 1, 1, 1, 0, 2, 2],
       [3, 1, 3, 4, 3, 4, 4],
       [2, 0, 1, 4, 3, 2, 0],
       [0, 1, 0, 4, 3, 4, 2],
       [0, 2, 1, 4, 3, 2, 1],
       [3, 4, 4, 4, 3, 3, 3]])
中间体

布尔值m(作为整数以获得更好的显示效果):

array([[0, 0, 0, 1, 0, 0, 0],
       [0, 0, 0, 1, 0, 0, 0],
       [0, 1, 1, 1, 1, 1, 1],
       [0, 0, 0, 1, 1, 0, 0],
       [0, 0, 0, 1, 1, 0, 0],
       [0, 0, 0, 0, 0, 0, 0],
       [0, 0, 0, 0, 0, 0, 0],
       [0, 0, 0, 0, 0, 0, 0]])

np.argsort(m).T的结果:

array([[0, 0, 0, 5, 0, 0, 0],
       [1, 1, 1, 6, 1, 1, 1],
       [2, 3, 3, 7, 5, 3, 3],
       [3, 4, 4, 0, 6, 4, 4],
       [4, 5, 5, 1, 7, 5, 5],
       [5, 6, 6, 2, 2, 6, 6],
       [6, 7, 7, 3, 3, 7, 7],
       [7, 2, 2, 4, 4, 2, 2]])
掩蔽

如果要屏蔽偏移值

out[np.take_along_axis(m.T, np.argsort(m).T, axis=0)] = -1

输出量:

array([[ 0,  3,  0,  1,  1,  1,  3],
       [ 4,  1,  0,  2,  2,  4,  1],
       [ 2,  1,  1,  1,  0,  2,  2],
       [ 3,  1,  3, -1,  3,  4,  4],
       [ 2,  0,  1, -1,  3,  2,  0],
       [ 0,  1,  0, -1, -1,  4,  2],
       [ 0,  2,  1, -1, -1,  2,  1],
       [ 3, -1, -1, -1, -1, -1, -1]])

相关问题