我需要一种方法来制作元组的二维数组,其中每个元组是该位置的一对索引。我需要这个没有for循环,因为我正在使用大矩阵。
例如,3x3案例将是:
array([[(0, 0), (0, 1), (0, 2)],
[(1, 0), (1, 1), (1, 2)],
[(2, 0), (2, 1), (2, 2)]], dtype=object)
我知道有numpy.indices并且在网上有一些建议(有一篇帖子询问这个here),但他们的建议基本上给出了一个3D数组。我需要一个2D,所以我可以将它传递给矢量化函数(这一个here)。我需要函数来处理这对索引,如果我将它传递给上面提到的3D版本,每个单独的索引值都会传递给函数,而不是该对。
但如果我的指数作为一个元组成对出现,这种情况就不会发生。尝试使用小型数组,它的工作原理。问题是,除了使用for循环迭代之外,我无法找到获取元组二维数组的方法。尝试过它需要太长时间。但我对编程很陌生,所以也许有人知道另一种方式吗?
答案 0 :(得分:0)
如果没有关于您需要多大阵列的详细信息,这很难回答。我怀疑nditer可以足够快地执行此操作。答案here引用了您可能有兴趣在c中执行此操作的原因。
如果像
那样的话import numpy as np
myarray = np.array([[(i, j) for i in range(1000)]
for j in range(1000)])
太慢,甚至无法运行它很难想象这里有一个合理的python解决方案
答案 1 :(得分:0)
这是一个元组列表:
In [137]: idx=np.ndindex(3,3)
In [138]: list(idx)
Out[138]: [(0, 0), (0, 1), (0, 2), (1, 0), (1, 1), (1, 2), (2, 0), (2, 1), (2, 2)]
我提到了vectorize
signature
参数。该版本使用ndindex
这样来迭代输入。
尝试从此列表中生成一个数组,得到一个18个元素的数组,可以重新转换为(3,3,2)。但是我们最近讨论了一个技巧(关于制作对象数组),我可以创建一个3x3的元组数组:
In [144]: res = np.empty((3,3),object)
In [145]: for idx in np.ndindex(3,3):
...: res[idx] = idx
...:
In [146]: res
Out[146]:
array([[(0, 0), (0, 1), (0, 2)],
[(1, 0), (1, 1), (1, 2)],
[(2, 0), (2, 1), (2, 2)]], dtype=object)
从相同大小的子列表列表中创建对象dtype数组有点棘手。 np.array
尽可能尝试创建基本数字dtype的多维数组。
对于它的价值,迭代列表比在数组上迭代更快。对象dtype数组的迭代速度比数字数据快,因为它已经包含像列表一样的对象指针。
def foo(ij):
print(ij)
return 4*ij[0]+ij[1]
使用对象dtype res
:
In [157]: f1 = np.vectorize(foo)
In [158]: f1(res)
(0, 0)
(0, 0)
(0, 1)
(0, 2)
(1, 0)
(1, 1)
(1, 2)
(2, 0)
(2, 1)
(2, 2)
Out[158]:
array([[ 0, 1, 2],
[ 4, 5, 6],
[ 8, 9, 10]])
使用签名和3d数组我得到同样的东西:
In [159]: f=np.vectorize(foo, signature='(n)->()')
In [160]:
In [160]: idx=np.ndindex(3,3)
In [161]: arr = np.array(list(idx)).reshape(3,3,2)
In [162]: f(arr)
[0 0]
[0 1]
[0 2]
[1 0]
[1 1]
[1 2]
[2 0]
[2 1]
[2 2]
Out[162]:
array([[ 0, 1, 2],
[ 4, 5, 6],
[ 8, 9, 10]])
但获取此数组的最佳方法是使用全数组操作:
In [164]: 4*arr[:,:,0]+arr[:,:,1]
Out[164]:
array([[ 0, 1, 2],
[ 4, 5, 6],
[ 8, 9, 10]])