[英]How to make a 2D numpy array with each element being a tuple of its indices?
I need a way to make a 2D array of tuples where each tuple is a pair of the indices at that position. 我需要一种制作元组的2D数组的方法,其中每个元组是该位置的一对索引。 I need this without for loops since i'm working with big matrices. 我需要没有for循环,因为我正在处理大型矩阵。
For example, the 3x3 case would be: 例如,3x3情况将是:
array([[(0, 0), (0, 1), (0, 2)],
[(1, 0), (1, 1), (1, 2)],
[(2, 0), (2, 1), (2, 2)]], dtype=object)
I know there is numpy.indices and there are pieces of advice online (there is a post asking about this here ), but what they suggests basically gives a 3D array. 我知道这里有numpy.indices,在线上有很多建议(这里有一篇帖子问这个问题 ),但是他们的建议基本上给出了一个3D数组。 I need a 2D one so I can pass it to a vectorized function (this one here ). 我需要一个2D模型,以便可以将其传递给矢量化函数( 此处为 )。 I need the function to work with the pair of indices and if I pass it the 3D version mentioned above, each individual index value gets passed to the function, instead of the pair. 我需要该函数使用一对索引,如果我将其传递给上述3D版本,则每个单独的索引值都会传递给该函数,而不是传递给该对。
But this doesn't happen if my indices come in a pair as a tuple. 但是,如果我的索引成对出现在一个元组中,则不会发生这种情况。 Tried it with small arrays and it works. 用小数组试过,它可以工作。 Problem is, I can't figure out a way of getting this 2D array of tuples, aside from iterating with for loops. 问题是,除了用for循环迭代外,我想不出一种获取2D元组数组的方法。 Tried it and it takes too long. 试了一下,花了太长时间。 But i'm new to programming, so maybe someone knows another way? 但是我是编程新手,所以也许有人知道另一种方式?
Here's a list of tuples: 这是一个元组列表:
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)]
I mentioned the vectorize
signature
parameter. 我提到了vectorize
signature
参数。 That version uses ndindex
like this to iterate on the inputs. 该版本使用ndindex
这样对输入进行迭代。
Trying make an array from this list results in a 18 element array, which can be reshaped to (3,3,2). 尝试从该列表中创建一个数组会导致一个18个元素的数组,可以将其重塑为(3,3,2)。 But with a trick we recently discussed (about making object arrays) I can make a 3x3 array of tuples: 但是我们最近讨论了一个技巧(关于制作对象数组),我可以制作一个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)
Making an object dtype array from lists of equal size sublists is a bit tricky. 从大小相等的子列表的列表中创建对象dtype数组有些棘手。 np.array
tries, where possible, to make a multidimensional array of basic numeric dtype. np.array
尽可能尝试制作基本数字np.array
的多维数组。
And for what it's worth, it's faster to iterate on a list than on an array. 而且就其价值而言,在列表上进行迭代比在数组上进行迭代要快。 An object dtype array iterates faster than a numeric one, since it already contains object pointers like a list. 对象dtype数组的迭代速度比数字数组快,因为它已经包含对象指针(如列表)。
def foo(ij):
print(ij)
return 4*ij[0]+ij[1]
With object dtype res
: 使用对象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]])
With signature, and 3d array I get the same thing: 使用签名和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]])
But the best way of getting this array is with whole-array operations: 但是获取此数组的最佳方法是使用全数组操作:
In [164]: 4*arr[:,:,0]+arr[:,:,1]
Out[164]:
array([[ 0, 1, 2],
[ 4, 5, 6],
[ 8, 9, 10]])
This is hard to answer without details on how large of an array you need. 如果没有有关所需阵列大小的详细信息,这很难回答。 I suspect nditer would be sufficiently fast to do this. 我怀疑nditer会足够快地执行此操作。 The answer here references why you might be interested in doing this in c instead. 这里的答案引用了为什么您可能会对在c中执行此操作感兴趣。
If something like 如果像
import numpy as np
myarray = np.array([[(i, j) for i in range(1000)]
for j in range(1000)])
is too slow to even run it's hard to imagine there's a reasonable python solution here 太慢甚至无法运行,很难想象这里有一个合理的python解决方案
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.