如何定义一个二维数组,其中每个元素是(x,y)坐标。

3
我有一个由(x,y)坐标组成的二维空间,想在Python中建模,并且想知道如何定义二维空间,以便我可以在一个点(x,y)上分配多个值。稍后,基于某些与坐标相关的计算,坐标上的值将会更改。
我考虑使用numpy数组来创建二维数组,该数组的大小基于用户输入。我首先创建了一个2D n*m numpy零数组,稍后在代码的某些部分进行了点的计算。但是这种方式每个点(x,y)只有一个值。
import numpy as np

x_coor=135

y_coor=120

grid=np.zeros((x_coor,y_coor)

有没有一种方法可以使grid[x,y] =(value1,value2),并且除了numpy数组之外,还有更好的定义网格的方法?

3个回答

3
您可以使用numpy来实现这个功能。一种方法是定义一个3d数组,如np.zeros((x_coor, y_coor, 2)),并将每个坐标保存在最后一个轴上。
另一种使用numpy获得所需结构的方法是定义一个tuplesndarray,并以上述方式更新每个点,即grid[x,y] = (value1,value2)。以下是您可以执行此操作的方法:
x_coor=135
y_coor=120

grid = np.zeros((5,3), dtype='i,i')
grid[0,0] = (1,2)
grid[2,2] = (5,1)
grid[1,0] = (3,5)

print(grid)
array([[(1, 2), (0, 0), (0, 0)],
       [(3, 5), (0, 0), (0, 0)],
       [(0, 0), (0, 0), (5, 1)],
       [(0, 0), (0, 0), (0, 0)],
       [(0, 0), (0, 0), (0, 0)]], dtype=[('f0', '<i4'), ('f1', '<i4')])

如果您想使用多个坐标一次性更新多个值,可以执行以下操作:
grid = np.zeros((5,3), dtype='i,i')

coordinates = np.array([(1,2),(2,2), (0,0)], dtype='i,i')
new_vals = np.array([(12,2),(4,1), (0,9)], dtype='i,i')

grid[tuple(zip(*coordinates))] = new_vals

print(grid)
array([[( 0, 9), ( 0, 0), ( 0, 0)],
       [( 0, 0), ( 0, 0), (12, 2)],
       [( 0, 0), ( 0, 0), ( 4, 1)],
       [( 0, 0), ( 0, 0), ( 0, 0)],
       [( 0, 0), ( 0, 0), ( 0, 0)]], dtype=[('f0', '<i4'), ('f1', '<i4')])

注意,元组是不可变的(inmutable),因此如果您计划对这些坐标执行操作,应该选择第一种方法。


我计划使用嵌套的for循环(for i in range(1,x_coor) for j in range(1,y_cor))对每个点进行计算。我确实需要对网格上的每个点执行计算。 - ironmacaron
在这种情况下,我会坚持使用方法1,即定义一个三维矩阵,并在最后一个轴上仅索引第一个或第二个元素。@ironmacaron - yatu

0
我不确定你的应用场景,但另一个数学启发式解决方案是将2D坐标存储为numpy的复数。这些存储了实部和虚部坐标的FP double,可以通过np.realnp.imag访问。这也使得减去复数和计算欧几里得距离变得容易,作为绝对值。
a = np.zeros((3, 3), dtype=np.cfloat)
a[2,2] = 1 + 1j

0
简短回答你的问题:你应该使用pandas而不是numpy数组。Numpy旨在加速数组计算,因此它不允许将数组的每个元素定义为列表。然而,Pandas数据框架允许这些类型的操作。以下是如何在Pandas中执行此类操作的方法,特别注意原始数据框架的灵活定义,以便稍后可以操纵更改包含在每个单元格中的列表的长度:
import numpy as np
import pandas as pd
df = pd.DataFrame(columns=[0,1,2])

for i in range(5):
df.loc[i,0] = np.arange(i)
df.loc[i,1] = np.arange(i)
df.loc[i,2] = np.arange(i)

print(df.loc[2,2])

这是单元格(2,2)中的条目:

array([0, 1])

现在您可以根据需要进行更改:

df.loc[2,2] = [10,20,30]

所以现在:

print(df.loc[2,2])

给你:

[10, 20, 30]

当我打印这个示例的 df 时,它会给出每个单元格中元素的行号-1个数,而不是所有单元格中的1或2个值。我查阅了一些 Pandas 文档,但无法弄清如何创建一个 n*m 的矩阵。抱歉,我对 Pandas 非常陌生,但在阅读了您的答案后非常感兴趣。 - ironmacaron
我创建了不同长度的单元格条目,以显示数据框可以容纳任意长度的条目... 您只需将 df.loc[I,0] = np.arange(i) 替换为 df.loc[I,0] = np.arange(2),即可使所有单元格都具有起始条目 (0,1)。之后,您可以操作任何单元格以采用任意长度的列表,而不仅仅是长度为 2。这样,它就更加灵活。 - HMReliable

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接