使用坐标列表切片numpy数组

3
考虑一个形状为(例如)(a,b,c)的numpy ndarray M和坐标列表[(b0,c0),(b1,c1),...,(bn,cn)]

我想要以下向量集合:[M [:,b0,c0],M [:,b1,c1],...,M [:,bn,cn]]。如何使用列表推导实现?

编辑:我需要一个适用于任意维度的解决方案,即在M.shape =(a,b,c,d)coordinates = [(b0,c0,d0),...,(bn,cn,dn)]等情况下返回像上面那样的列表,并且也适用于更高维的情况。

2个回答

8

你不希望用列表推导式来做这件事情。"高级索引"可以一次性完成整个过程。我建议使用:

inds = [(b0,c0),(b1,c1),...,(bn,cn)]

#inds_array[0] = [b0, b1, b2, ...]
inds_array = np.moveaxis(np.array(inds), -1, 0)

M[np.index_exp[:] + tuple(inds_array)]

演示:

>>> x, y, z = np.ogrid[:2,:4,:5]
>>> M = 100*x + 10*y + z
>>> M.shape
(2, 4, 5)
>>> inds = [(0, 0), (2, 1), (3, 4), (1, 2)]
>>> inds_array = np.moveaxis(np.array(inds), -1, 0); inds_array
array([[0, 2, 3, 1],
       [0, 1, 4, 2]])
>>> M[np.index_exp[:] + tuple(inds_array)]  # same as M[:, [0, 2, 3, 1], [0, 1, 4, 2]]
array([[  0,  21,  34,  12],
       [100, 121, 134, 112]])

可能有助于展示索引表达式的样子:slice(None), ....。我不得不查找 index_exp 来了解它与 s_ 的区别,而且如果没有运行示例,我无法想象 inds_array 是什么样子的。 - hpaulj

5
如果您想要这些向量的列表,您可以简单地使用:
[M[:,<b>bi,ci</b>] for <b>bi,ci in coordinates</b>]

其中coordinates当然是您的列表:

coordinates = [(b0,c0),(b1,c1),...,(bn,cn)]

编辑:如果需要进行多变量切片,您可以使用slice(None)和剩余的索引调用__getitem__方法:

[M.<b>[(slice(None),*coord)]</b> for coord in coordinates]

对于 ;或者:

[M[<b>(slice(None),)+coord</b>] for coord in coordinates]

适用于其他版本。


1
糟糕!你比我快了几秒钟。 - Christian Dean
谢谢!当然,这个方法是有效的,但我意识到在提问时把问题简化得太多了。让我编辑一下。 - Ziofil
@Ziofil:但你明确要求使用列表推导式。顺便说一下,dv 没有。 - Willem Van Onsem
@Ziofil:更新后的示例是否可用(在Python-3.5中)? - Willem Van Onsem
直接调用 .__getitem__() 被扣分。唯一需要这样做的情况是使用 super,而这不是那种情况。 - Eric

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接