无需在 Python 中迭代即可创建 Numpy 数组

Posted

技术标签:

【中文标题】无需在 Python 中迭代即可创建 Numpy 数组【英文标题】:Creating Numpy-Arrays without iterating in Python 【发布时间】:2015-05-19 09:13:56 【问题描述】:

假设我有一个形状为 (2,3) 的 numpy 数组,其中填充了浮点数。

我还需要一个包含所有可能的 X 和 Y 值组合的数组(它们在数组中的对应位置)。是否有类似 simpe 的函数可以从 numpy 数组中将索引作为元组获取,在该数组中我不需要 for 循环遍历数组?

示例代码:

arr=np.array([np.array([1.0,1.1,1.2]),
              np.array([1.0,1.1,1.2])])
indices=np.zeros([arr.shape[0]*arr.shape[1]])

#I want an array of length 6 like np.array([[0,0],[0,1],[0,2],[1,0],[1,1], [1,2]])
#Code so far, iterates though :(
ik=0
for i in np.arange(array.shape[0]):
    for k in np.arange(array.shape[1]):
        indices[ik]=np.array([i,k])
        ik+=1

在此之后,我还想创建一个数组,其中包含“XYZ 坐标”的“索引”数组的长度,就像每个包含 XY“索引”和“arr”中的 Z 值的元素一样。有没有比这更简单的方法(如果可能的话,无需再次遍历数组):

xyz=np.zeros(indices.shape[0])
for i in range(indices.shape[0]):
    xyz=np.array([indices[i,0],indices[i,1],arr[indices[i,0],indices[i,1]]

【问题讨论】:

【参考方案1】:

你可以使用np.ndindex:

indices = np.ndindex(arr.shape)

这将提供一个迭代器而不是一个数组,但您可以轻松地将其转换为列表:

>>> list(indices)
[(0, 0), (0, 1), (0, 2), (1, 0), (1, 1), (1, 2)]

然后您可以将索引与原始数组沿第二维堆叠:

np.hstack((list(indices), arr.reshape((arr.size, 1))))

【讨论】:

【参考方案2】:

对于您的索引:

indices = np.concatenate((np.meshgrid(range(arr.shape[0]), range(arr.shape[1])))

【讨论】:

【参考方案3】:

可能有很多方法可以实现这一点......一个可能的解决方案如下。

第一个问题可以使用np.unravel_index解决

max_it = arr.shape[0]*arr.shape[1]
indices = np.vstack(np.unravel_index(np.arange(max_it),arr.shape)).T

然后可以构造第二个数组

xyz = np.column_stack((indices,arr[indices[:,0],indices[:,1]]))

时间安排

在你的数组上timeit 给我的代码10000 loops, best of 3: 27.7 µs per loop(grc 的解决方案需要10000 loops, best of 3: 39.6 µs per loop

在带有shape=(50,60) 的较大数组上,我有1000 loops, best of 3: 247 µs per loop(grc 的解决方案需要100 loops, best of 3: 2.17 ms per loop

【讨论】:

以上是关于无需在 Python 中迭代即可创建 Numpy 数组的主要内容,如果未能解决你的问题,请参考以下文章

在 Python 中无需单击即可执行函数 | Pyside [重复]

QTableView 单元格文本对齐 - 无需迭代即可更改

Redis Python - 如何在python中根据特定模式删除所有键,无需python迭代

Python:“numpy.amax”与 Python 的“max”:“int”对象不可迭代

cupy或numpy中"数组"与"矩阵"的区别

在 Python 中无需重新启动应用程序即可检索 MySQL 数据库的新行