Arrays NumPy:按元组列表索引数组-如何正确执行?
我处于以下情况-我有以下情况:Arrays NumPy:按元组列表索引数组-如何正确执行?,arrays,numpy,indexing,Arrays,Numpy,Indexing,我处于以下情况-我有以下情况: 多维numpy数组aofndimensions t,由k行(元组)组成的数组,每个行(元组)包含n元素。换句话说,该数组中的每一行都是a 我想要的:从a返回一个带有k标量元素的数组b,其中Ith元素是b中a与t中的Ith元组建立索引的结果 看起来很琐碎。但是,以下方法不起作用 def-get(a,t): #错误的结果+花费的时间太长 返回a[t] 我必须采取迭代的方法,即以下方法可以正确工作: def-get(a,t): res=[] 对于t中的ind: a
- 多维numpy数组
ofa
dimensionsn
,由t
行(元组)组成的数组,每个行(元组)包含k
元素。换句话说,该数组中的每一行都是n
a
a
返回一个带有k
标量元素的数组b
,其中I
th元素是b
中a
与t
中的I
th元组建立索引的结果
看起来很琐碎。但是,以下方法不起作用
def-get(a,t):
#错误的结果+花费的时间太长
返回a[t]
我必须采取迭代的方法,即以下方法可以正确工作:
def-get(a,t):
res=[]
对于t中的ind:
a_标量=a
我在印度:
a_标量=a_标量[i]
#_标量现在是标量
res.append(一个标量)
返回res
这是可行的,除了考虑到
a
中的每个维度都有30多个元素外,当n
达到5个以上时,过程确实会变得非常缓慢。我知道这将是缓慢的,但是,我想利用numpy的功能,因为我相信它将大大加快这一过程。正确的关键是理解索引列表和元组的作用。通常这两者被视为相同的,但在numpy
索引中,元组、列表和数组传递不同的信息
In [1]: a = np.arange(12).reshape(3,4)
In [2]: t = np.array([(0,0),(1,1),(2,2)])
In [4]: a
Out[4]:
array([[ 0, 1, 2, 3],
[ 4, 5, 6, 7],
[ 8, 9, 10, 11]])
In [5]: t
Out[5]:
array([[0, 0],
[1, 1],
[2, 2]])
你试过:
In [6]: a[t]
Out[6]:
array([[[ 0, 1, 2, 3],
[ 0, 1, 2, 3]],
[[ 4, 5, 6, 7],
[ 4, 5, 6, 7]],
[[ 8, 9, 10, 11],
[ 8, 9, 10, 11]]])
那有什么问题吗?它运行,但选择了一个(3,2)行数组a
。也就是说,它只将t
应用于第一个维度,有效地a[t,:]
。您希望在所有维度上建立索引,某种类型的a[t1,t2]
。这与a[(t1,t2)]
-索引的元组相同
In [10]: a[tuple(t[0])] # a[(0,0)]
Out[10]: 0
In [11]: a[tuple(t[1])] # a[(1,1)]
Out[11]: 5
In [12]: a[tuple(t[2])]
Out[12]: 10
或者同时做所有的事情:
In [13]: a[(t[:,0], t[:,1])]
Out[13]: array([ 0, 5, 10])
另一种编写方法是n
列表(或数组),每个维度一个:
In [14]: a[[0,1,2],[0,1,2]]
Out[14]: array([ 0, 5, 10])
In [18]: tuple(t.T)
Out[18]: (array([0, 1, 2]), array([0, 1, 2]))
In [19]: a[tuple(t.T)]
Out[19]: array([ 0, 5, 10])
更一般地,在a[idx1,idx2]
arrayidx1
中,对idx2
进行广播以产生完整的选择数组。这里两个数组是1d和匹配的,选择是您的t
对集。但同样的原则也适用于选择一组行和列,a[[0],[2],[0,2,3]
使用[10]和下面的想法,您的get
可以通过以下方式加快速度:
In [20]: def get(a, t):
...: res = []
...: for ind in t:
...: res.append(a[tuple(ind)]) # index all dimensions at once
...: return res
...:
In [21]: get(a,t)
Out[21]: [0, 5, 10]
如果t
实际上是一个元组列表(而不是由元组构建的数组),那么get可以是:
In [23]: tl = [(0,0),(1,1),(2,2)]
In [24]: [a[ind] for ind in tl]
Out[24]: [0, 5, 10]
探索使用np.ravel\u多重索引 创建一些测试数据
arr = np.arange(10**4)
arr.shape=10,10,10,10
t = []
for j in range(5):
t.append( tuple(np.random.randint(10, size = 4)))
print(t)
# [(1, 8, 2, 0),
# (2, 3, 3, 6),
# (1, 4, 8, 5),
# (2, 2, 6, 3),
# (0, 5, 0, 2),]
ta = np.array(t).T
print(ta)
# array([[1, 2, 1, 2, 0],
# [8, 3, 4, 2, 5],
# [2, 3, 8, 6, 0],
# [0, 6, 5, 3, 2]])
arr.ravel()[np.ravel_multi_index(tuple(ta), (10,10,10,10))]
# array([1820, 2336, 1485, 2263, 502]
np.ravel_multi_index基本上是从输入数组的元组计算索引,将其转换为一个从形状开始的扁平数组(在本例中)(10,10,10,10)
这能满足你的需要吗?够快吗