我有一个矩阵
import numpy as np
matrix = np.array([[1, 2, 3],
[4, 5, 6],
[7, 8, 9]])
我想用它表示笛卡尔坐标上的离散二维物理空间。因此,例如,当访问值时,我会得到
matrix[0,0] = 7
,matrix[1,2] = 6
,matrix[3,3] = 3
.
我怎样才能做到这一点?我尝试过使用
np.meshgrid
,但就我设法实施它而言,结果并不是我想要的。我正在寻找的东西可以通过每次我尝试访问一个值时转置矩阵来完成,但我想要一种方法来直接更改矩阵的索引。
谢谢!
np.flip
:
vmatrix = np.flip(matrix, axis=0)
print(vmatrix)
# Output
array([[7, 8, 9],
[4, 5, 6],
[1, 2, 3]])
用法:
>>> vmatrix[0, 0]
7
>>> vmatrix[1, 2]
6
>>> vmatrix[2, 2]
3
np.pad
:
vmatrix = np.pad(np.flip(matrix, axis=0), [[1, 0], [1, 0]])
print(vmatrix)
# Output
[[0 0 0 0]
[0 7 8 9]
[0 4 5 6]
[0 1 2 3]]
用法:
>>> vmatrix[1, 1]
7
>>> vmatrix[2, 3]
6
>>> vmatrix[3, 3]
3
您还可以子类化ndarray并覆盖
__getitem__
和__setitem__
方法。
关于
numpy.array.__getitem__
是不可写的,建议通过其他方式访问值。
在我看来,使用
numpy.flip
不适合这种情况,因为它会创建数组的副本,导致效率低下和不必要的内存使用。
对于小规模数据,子类化
ndarray
是一个不错的选择。但是,对于大规模数据,最好忍受限制,以防止随机访问造成的时间浪费。
我会为你的问题提供解决方案。虽然我会解释为什么这种方法非常笨拙,并且会在以后的实验中导致问题。我建议为此查看 meshgrid。 这里 是一个简单的例子,如何使用 meshgrid 在 2D 笛卡尔平面上执行计算。我认为这是标准和直接的方式,因此是特权方式。
之前,我会介绍一些变量。表示
x_values = np.arange(-2, 2+1)
、y_values = np.arrange(-1, 1+1)
之间的笛卡尔平面的矩阵:
matrix = np.array[
[ 1, 1, 0, 2, 2],
[ 0, 0, 0, 0, 0],
[ 3, 3, 0, 4, 4]]
我们将这个矩阵的索引表示为
i
和j
。我们还将注意到 x
和 y
作为我们的笛卡尔索引。你想要的是从(x, y)
到(i, j)
的映射。例如,从 (2, 1)
你想要左上角的值与矩阵索引 (0, 4)
.
最后引入的变量是
i_origin
和j_origin
。这些变量是平面i
的笛卡尔原点的j
和(0, 0)
。我们可以做i_origin = matrix.shape[0] // 2
和j_origin = matrix.shape[1] // 2
。我们将使用 i_origin
作为线条索引的偏移量 - 垂直 - 所以对于 y
和 j_origin
用于 x
如果你拿一支铅笔和一张纸,我想我们可以同意:
i = i_origin - y
j = j_origin + x
所以,我们可以写两个短函数:
def map_to_i(i_origin: int, y: int) -> int:
return i_origin - y
def map_to_j(j_origin: int, x: int) -> int:
return j_origin - x
如果你愿意,我们甚至可以创建一个包含 (i, j) 元组的函数:
def map_to_matrix_indices(i_origin: int, j_origin: int, x: int, y: int) -> tuple[int, int]:
return map_to_i(i_origin, y), map_to_j(j_origin, x)
我们可以简单地写:
>>> matrix[map_to_matrix_indices(i_origin, j_origin, 2, 1)]
2
好吧,我们可以说我们有您的解决方案,但是这种方法带来了很多问题:
CartesianMatrix
- 例如 - 并将我们的函数放在它的方法中。您可以从ndarray
继承或组合它。这可能是可行的,但需要额外的工作。 (注:实际去做会很有趣)一般来说,你必须把你的新类的接口设置成和ndarray一样才没有问题。否则,您将不得不为遇到的每个问题找到解决方法,因为您没有通过标准方式访问/设置索引。
注意:对象的接口是对象必须如何表现。