numpy Python:如何将矩阵索引转换为笛卡尔索引?

2j4z5cfb  于 2023-05-17  发布在  Python
关注(0)|答案(3)|浏览(117)

我有一个矩阵

import numpy as np
matrix = np.array([[1, 2, 3],
                   [4, 5, 6],
                   [7, 8, 9]])

我想用它来表示一个离散的二维物理空间,在笛卡尔坐标系中。例如,当访问值时,我会得到matrix[0,0] = 7matrix[1,2] = 6matrix[3,3] = 3
我怎么能做到呢?我尝试过使用np.meshgrid,但就我设法实现它而言,结果并不是我要找的。我所寻找的可以通过转置矩阵每次我试图访问一个值,但我想一种方法,只是改变索引的矩阵直接完成。
谢谢!

zpf6vheq

zpf6vheq1#

您可以使用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

您还可以Subclassing ndarray和覆盖__getitem____setitem__方法。

ibps3vxo

ibps3vxo2#

我将为您的问题提供解决方案。尽管我会解释为什么这种方法非常笨拙,并且会在稍后的实验中导致问题。我建议看看meshgrid。Here是一个简单的例子,如何使用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]]

我们将该矩阵的索引表示为ij。我们还将注意到xy作为我们的笛卡尔指数。您需要的是从(x, y)(i, j)的Map。例如,从(2, 1)开始,您需要左上角的值与矩阵索引(0, 4)
最后引入的变量是i_originj_origin。这些变量是ij,它们是平面(0, 0)的笛卡尔原点。我们可以做i_origin = matrix.shape[0] // 2j_origin = matrix.shape[1] // 2。我们将使用i_origin作为行索引的偏移量- vertical -所以对于yj_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

问题

好吧,我们可以说我们有你的解决方案,但这种方法带来了一系列问题:

  • 访问/设置您的值的界面不标准。因此,它可能不适合库。另外,你失去了一部分来自numpy的广播。
  • 解决这个问题的一种方法是实现一个类CartesianMatrix-例如-并将我们的函数放在它的方法中。您可以从ndarray继承或组合它。这可能是可行的,但需要更多的工作。(注:实际上会很有趣)
  • 这样写,它不能被推广到更多的维度。我认为它可以很容易地正式化。

一般来说,您必须将新类的接口设置为与ndarray相同才不会有问题。否则,你将不得不为你遇到的每个问题找到一个解决方案,因为你没有通过标准的方式访问/设置索引。
注意:对象的接口是对象必须表现的方式。

unguejic

unguejic3#

考虑到numpy.ndarray.__getitem__不可写的事实,建议以另一种方式访问值。
numpy.flip函数可用于沿着指定轴翻转或反转数组中元素的顺序。这在各种数据处理和分析任务中可能是有用的,例如图像处理、信号处理和数据操纵。
我想为我之前的错误回答向你道歉。这个问题的最佳解决方案是使用numpy.flip函数。

相关问题