gpt4 book ai didi

python - 迭代二维数组的 'orthogonal' 对角线的更多 numpy 方法

转载 作者:太空宇宙 更新时间:2023-11-04 07:22:33 25 4
gpt4 key购买 nike

我有以下代码,它沿着与通常由 np.diagonal 返回的对角线正交的对角线进行迭代。 .它从位置 (0, 0) 开始并朝着右下坐标移动。

代码按预期工作,但它的所有循环都不是很 NumPy ,而且效率低下必须创建许多数组来完成这个技巧。

所以我想知道是否有更好的方法来做到这一点,因为我不知道如何跨越我的数组或使用 numpy 的对角线方法以更好的方式来做到这一点(尽管我希望有一些我看不到的技巧)。

import numpy as np

A = np.zeros((4,5))

#Construct a distance array of same size that uses (0, 0) as origo
#and evaluates distances along first and second dimensions slightly
#differently so that no values in the array is the same
D = np.zeros(A.shape)
for i in range(D.shape[0]):
for j in range(D.shape[1]):
D[i, j] = i * (1 + 1.0 / (grid_shape[0] + 1)) + j

print D
#[[ 0. 1. 2. 3. 4. ]
# [ 1.05882353 2.05882353 3.05882353 4.05882353 5.05882353]
# [ 2.11764706 3.11764706 4.11764706 5.11764706 6.11764706]
# [ 3.17647059 4.17647059 5.17647059 6.17647059 7.17647059]]

#Make a flat sorted copy
rD = D.ravel().copy()
rD.sort()

#Just to show how it works, assigning incrementing values
#iterating along the 'orthagonal' diagonals starting at (0, 0) position
for i, v in enumerate(rD):

A[D == v] = i

print A
#[[ 0 1 3 6 10]
# [ 2 4 7 11 14]
# [ 5 8 12 15 17]
# [ 9 13 16 18 19]]

编辑

澄清一下,我想按元素遍历整个 A但按照上面代码调用的顺序执行(显示在最后的 print 中)。

迭代沿对角线的哪个方向并不重要(如果 1 和 2 交换位置,以及 3 和 5 等在 A 中)仅对角线与 A 的主对角线正交(产生的主对角线)通过 np.diag(A) )。

这个问题的应用/原因在我之前的问题中(在该问题底部的解决方案部分):Constructing a 2D grid from potentially incomplete list of candidates

最佳答案

这是一种避免 Python for 循环的方法。

首先,让我们看看我们的加法表:

import numpy as np
grid_shape = (4,5)
N = np.prod(grid_shape)

y = np.add.outer(np.arange(grid_shape[0]),np.arange(grid_shape[1]))
print(y)

# [[0 1 2 3 4]
# [1 2 3 4 5]
# [2 3 4 5 6]
# [3 4 5 6 7]]

关键思想是,如果我们按顺序访问加法表中的总和,我们将按所需顺序遍历数组。

我们可以使用 np.argsort 找出与该订单关联的索引:

idx = np.argsort(y.ravel())
print(idx)
# [ 0 1 5 2 6 10 3 7 11 15 4 8 12 16 9 13 17 14 18 19]

idx 是金色的。它基本上是迭代任何形状为 (4,5) 的二维数组所需的一切,因为二维数组只是 reshape 的一维数组。

如果您的最终目标是生成数组 A,如您在帖子末尾显示的那样,那么您可以再次使用 argsort:

print(np.argsort(idx).reshape(grid_shape[0],-1))
# [[ 0 1 3 6 10]
# [ 2 4 7 11 14]
# [ 5 8 12 15 17]
# [ 9 13 16 18 19]]

或者,如果您需要为 A 分配其他值,也许这会更有用:

A = np.zeros(grid_shape)
A1d = A.ravel()
A1d[idx] = np.arange(N) # you can change np.arange(N) to any 1D array of shape (N,)
print(A)
# [[ 0. 1. 3. 6. 10.]
# [ 2. 4. 7. 11. 15.]
# [ 5. 8. 12. 16. 18.]
# [ 9. 13. 14. 17. 19.]]

我知道您要求通过数组迭代的方法,但我想展示上面的内容,因为通过整个数组赋值或 numpy 函数调用(如 np.argsort)生成数组已完成以上可能比使用 Python 循环更快。但是如果你需要使用 Python 循环,那么:

for i, j in enumerate(idx):
A1d[j] = i

print(A)
# [[ 0. 1. 3. 6. 10.]
# [ 2. 4. 7. 11. 15.]
# [ 5. 8. 12. 16. 18.]
# [ 9. 13. 14. 17. 19.]]

关于python - 迭代二维数组的 'orthogonal' 对角线的更多 numpy 方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14258317/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com