不使用循环从索引中提取值

Extracting values from indices without using loops

所以我有一个包含数据的矩阵和一个包含我应该从矩阵中提取哪些数据的信息的向量。真正的矩阵要长得多,但下面是一个简短的版本,只是为了说明我的意思。

Data matrix = array([[1 2 3],[0 3 5],[1 4 4]]) 
Info vector = array([[1], [0], [2]])
Answer matrix = array([[2 (the second element)], [0(the first element)], 4(the third element)]])

简单的 for 循环:

length_data = data.shapes[0]
for i in xrange(length_data)
    answer[i] = data[info[i],i]

我知道如何使用简单的 for 循环来完成此操作,但如何使用矢量化来完成此操作而不使用任何循环?

谢谢!

问题的小补充:如果我想要答案如下怎么办

Answer matrix = array([[0 2 0], [0 0 0], [0 0 4]])

您需要像这样 zip 将两个列表放在一起,以便另一个索引第一个列表。

answer = map(lambda x: x[0][x[1]], zip(data, info)) # [2, 0, 4]
>>> data = [[1, 2, 3], [0, 3, 5], [1, 4, 4]]
>>> info = [1, 0, 2]
>>> map(list.__getitem__, data, info)
[2, 0, 4]

没有循环?好的,没有循环。

>>> m = [[1,2,3], [0,3,5], [1,4,4]]
>>> v = [1,0,2]
>>> def match(a, b):
...     return match_core([], iter(a), iter(b))
...
>>> def match_core(l, a, b):
...     l.append(next(a)[next(b)])
...     try:
...         return match_core(l, a, b)
...     except StopIteration:
...         return l
...
>>> match(m, v)
[2, 0, 4]

假设你的数据更像是numpy数组或者你安装了numpy,那么可以使用np.choose:

来实现
In [3]: import numpy as np

In [4]: matrix = np.array([[1, 2, 3],[0, 3, 5],[1, 4, 4]])

In [5]: vector = np.array([[1], [0], [2]])

In [6]: np.choose(vector.flat, matrix.T)
Out[6]: array([2, 0, 4])

choose(a, choices, out=None, mode='raise') Construct an array from an index array and a set of arrays to choose from.

使用vector.flat获取[1, 0, 2]的迭代器; matrix.T 获取当前 matrix 的转置视图,np.choose 将使用 vector 作为索引数组。

尽管使用 choose 仍然会遍历 vector 数组。

Numpy 允许您使用列表或数组进行索引,因此您只需要使用 data[i, info],其中 i 是循环中的整个范围,而不仅仅是一个元素,并且 info 是一维数组。

import numpy as np
data = np.array([[1, 2, 3], [0, 3, 5], [1, 4, 4]])
info = np.array([1, 0, 2])

i = np.arange(data.shape[0])
print(data[i, info])
# array([2, 0, 4])

很难从你的问题中判断出来,因为你实际上没有 post 工作代码,但看起来你的信息数组的形状可能是 (3, 1) 而不是 (3,)。在这种情况下,您只需要添加一个 ravel:

print(data[i, info.ravel()])
# array([2, 0, 4])