我想了解各种2d数组转换方法。
我有一个方法,它返回一个(x, y)坐标索引列表,对应于应该在2d数组中删除的值。下面的值应该代替要删除的值,下面的值应该移动到它们的位置,等等。在数组的底部,将随机生成新值(这里不需要帮助,并且超出范围),在下面的示例输出中用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],
])
欢迎各种解决方案,简单高效的首选,示范性答案赞赏!
从上面的例子中注入coordinates
和test
变量;
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)
创建所需的输出,但是必须有许多其他更干净,更有效,更简单等的方法。
注意:您使用的坐标是倒置的。Numpy索引将是(row, col),而您使用(col, row)。下面的解决方案使用换位来适应你的坐标
我会制作一个布尔掩码来标识要删除/移位的位置。然后使用argsort
将True
的值推到最后,并使用这些索引对原始数组进行重新排序。
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]])
Result ofnp.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]])