NumPy文档here告诉我们以下内容不起作用:
>>> test_array[np.array([0,2,4]), np.array([0,1])]
<type 'exceptions.ValueError'>: shape mismatch: objects cannot be
broadcast to a single shape
但是,如果我们必须做某种事情,应该怎么做?目前,我使用Python列表理解:
test_array = np.array([ [ [1, 2, 3], [4, 5, 6], [7, 8, 9] ],
[ [10, 11, 12], [13, 14, 15], [16, 17, 18] ],
[ [19, 20, 21], [22, 23, 24], [25, 26, 27] ],
[ [28, 29, 30], [31, 32, 33], [34, 35, 36] ] ])
xs = [0, 2, 3]
ys = [0, 2]
>>> np.array([test_array[x, y] for x, y in list(itertools.product(xs, ys))])
array([[ 1, 2, 3],
[ 7, 8, 9],
[19, 20, 21],
[25, 26, 27],
[28, 29, 30],
[34, 35, 36]])
我怀疑这是否有效!
答案 0 :(得分:1)
你发布的代码不起作用,所以有点猜测,但我认为这就是你所追求的:
>>> y = np.arange(30).reshape(5, 6)
>>> xs = [0, 2, 4]
>>> ys = [0, 1]
>>> np.array([y[xy] for xy in itertools.product(xs, ys)])
array([ 0, 1, 12, 13, 24, 25])
>>> y[np.array(xs)[:, None], ys]
array([[ 0, 1],
[12, 13],
[24, 25]])
>>> y[np.array(xs)[:, None], ys].ravel()
array([ 0, 1, 12, 13, 24, 25])
编辑您的更新代码可以同样工作,但不是很漂亮:
>>> test_array[np.array(xs)[:, None], ys].reshape(-1, test_array.shape[-1])
array([[ 1, 2, 3],
[ 7, 8, 9],
[19, 20, 21],
[25, 26, 27],
[28, 29, 30],
[34, 35, 36]])
答案 1 :(得分:1)
如果在numpy中使用np.ix_
进行索引,则为此类。
import numpy as np
test_array = np.array([ [ [1, 2, 3], [4, 5, 6], [7, 8, 9] ],
[ [10, 11, 12], [13, 14, 15], [16, 17, 18] ],
[ [19, 20, 21], [22, 23, 24], [25, 26, 27] ],
[ [28, 29, 30], [31, 32, 33], [34, 35, 36] ] ])
xs = [0, 2, 3]
ys = [0, 2]
res = test_array[np.ix_(xs, ys)]
print res.shape
# (3, 2, 3)
结果是(3,2,3),因为xy,ys的长度和数组的最后一个维度分别为3,2,3。如果您希望结果为(6,3),只需在索引后重新整形:
i, j, k = res.shape
res = res.reshape((i * j, k))
print res.shape
# (6, 3)
print res
# array([[ 1, 2, 3],
# [ 7, 8, 9],
# [19, 20, 21],
# [25, 26, 27],
# [28, 29, 30],
# [34, 35, 36]])
对于任何有兴趣的人来说,np.ix_
只是一个便条,只是@Jamie答案中使用的魔术广播的便利功能。如果您想知道它的工作原理,请查看他的答案,并在numpy's broadcasting上阅读。
答案 2 :(得分:0)
这种语法是可行的。
tmp = y[np.array([0, 2, 4]), np.array([0, 1, 1])]
给出与以下相同的结果:
tmp = np.array([y[0, 0], y[2, 1], y[4, 1]])
以下是一个例子:
>>> y = np.arange(15).reshape(5, 3)
[[ 0 1 2]
[ 3 4 5]
[ 6 7 8]
[ 9 10 11]
[12 13 14]]
>>> y[np.array([0, 2, 4]), np.array([0, 1, 1])]
[ 0 7 13]
>>> np.array([y[0, 0], y[2, 1], y[4, 1]])
[ 0 7 13]
因此,您提出的语法是错误的,因为两个索引列表不具有相同的形状。
答案 3 :(得分:0)
这不是一般的解决方案,但它符合您的示例的期望:
import numpy as np
import itertools as it
test_array = np.array([ [ [1, 2, 3], [4, 5, 6], [7, 8, 9] ], [ [10, 11, 12], [13, 14, 15], [16, 17, 18] ], [ [19, 20, 21], [22, 23, 24], [25, 26, 27] ], [ [28, 29, 30], [31, 32, 33], [34, 35, 36] ] ])
xs = [0, 2, 3]
ys = [0, 2]
expected = np.array([test_array[x, y] for x, y in list(it.product(xs, ys))])
new = test_array[xs,...][:,ys, ...]
new = new.reshape(np.multiply(*new.shape[:-1]), new.shape[-1])
assert np.all(new == expected)