将二维数组的每个元素映射到python中对应的(x,y)坐标
Posted
技术标签:
【中文标题】将二维数组的每个元素映射到python中对应的(x,y)坐标【英文标题】:Mapping every element of a 2D array to its corresponding (x,y) coordinate in python 【发布时间】:2022-01-17 07:29:39 【问题描述】:我有两个一维数组,它们给出了 x 和 y 的值范围——例如:
x = np.array([0,1,2])
y = np.array([8,9])
我还有一个对应的二维数组,它给出了与每个可能的 (x,y) 组合相关的 z 值——例如:
z = np.array([['A','B'],
['C','D'],
['E','F']])
注意在这个例子中 z 是一个 3x2 数组,每一行对应一个给定的 x 值,每列对应一个给定的 y 值(顺序对于这个映射很重要)。
我想要的是将这 3 个数组组合成一个坐标值对的一维列表——例如:
result = [(0,8,'A'),
(0,9,'B'),
(1,8,'C'),
(1,9,'D'),
(2,8,'E'),
(2,9,'F')]
使用 for 循环绝对有一种蛮力的方法,但是使用预先存在的 numpy 或 python 例程是否有更简单/更快的方法?我的猜测是它可能涉及 np.meshgrid()、zip() 或 itertools,但我无法弄清楚。任何帮助将不胜感激!
【问题讨论】:
由于你想要一个元组列表,你不能使用“直接”numpy
方法(这会产生一个具有统一 dtype 的多维数组)。 np.ndenumerate(z)
很简单,虽然不能自定义索引。
【参考方案1】:
尝试将itertools.product
与zip
结合使用并进行列表理解。您还需要使用 numpy 解开二维列表
from itertools import product
import numpy as np
x = np.array([0,1,2])
y = np.array([8,9])
z = np.array([['A','B'],
['C','D'],
['E','F']])
result = [(x,y,z) for (x,y),z in zip(product(x, y), np.hstack(z))]
# [(0, 8, 'A'), (0, 9, 'B'), (1, 8, 'C'), (1, 9, 'D'), (2, 8, 'E'), (2, 9, 'F')]
【讨论】:
【参考方案2】:您可以将itertools.product
和zip
产品与扁平化的z
一起使用:
from itertools import product
out = [tuple(list(i)+[j]) for i,j in zip(product(x,y),z.flatten())]
输出:
[(0, 8, 'A'), (0, 9, 'B'), (1, 8, 'C'), (1, 9, 'D'), (2, 8, 'E'), (2, 9, 'F')]
【讨论】:
【参考方案3】:你也可以使用np.meshgrid
,比itertools.product
快:
combs = np.stack(np.meshgrid(x, y), axis=-1).reshape(-1, 2)
print(combs)
[[0 8]
[1 8]
[2 8]
[0 9]
[1 9]
[2 9]]
将不同类型的数据保存在同一个数组中并不是一个好主意。因此,如果您真的需要它,请以迭代为代价将其替换为动态类型:
[(*c, id) for c, id in zip(combs, z.ravel())]
>>> [(0, 8, 'A'), (1, 8, 'B'), (2, 8, 'C'), (0, 9, 'D'), (1, 9, 'E'), (2, 9, 'F')]
【讨论】:
以上是关于将二维数组的每个元素映射到python中对应的(x,y)坐标的主要内容,如果未能解决你的问题,请参考以下文章