Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/arrays/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Arrays NumPy:按元组列表索引数组-如何正确执行?_Arrays_Numpy_Indexing - Fatal编程技术网

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数组
    a
    of
    n
    dimensions
  • 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]
array
idx1
中,对
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)

这能满足你的需要吗?够快吗