首页 > 解决方案 > 如何用另一个ndarray索引一个ndarray?

问题描述

我在 python/numpy 中做一些机器学习的东西,我想用一维 ndarray 索引一个二维 ndarray,这样我就得到一个带有索引值的一维数组。

我让它与一些丑陋的代码一起工作,我想知道是否有更好的方法,因为对于像 python + numpy 这样好的语言和模块组合来说,这似乎是不自然的。

   a = np.arange(50).reshape(10, 5) # Array to be indexed
   b = np.arange(9, -1, -2) # Indexing array
   print(a)
   print(b)
   print(a[b, np.arange(0, a.shape[1]).reshape(1,a.shape[1])])
   #Prints:
   [[ 0  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 37 38 39]
    [40 41 42 43 44]
    [45 46 47 48 49]]

   [9 7 5 3 1]

   [[45 36 27 18  9]]

这正是我想要的(即使技术上是二维 ndarray),但这似乎非常复杂。有没有更整洁的方式?

编辑:为了澄清,我实际上不想要一维数组,这解释得非常糟糕。我实际上确实想要一个长度为 1 的维度,因为这是我以后处理它所需要的,但这很容易通过一个reshape()语句来实现。很抱歉造成混淆,我只是将我的实际代码与更一般的问题混合在一起。

标签: pythonnumpy

解决方案


你可以用它np.diagonal来得到你想要的。不需要reshape或索引。这里棘手的部分是确定您想要获得的模式,它基本上是a[b]矩阵的对角线元素。

a = np.arange(50).reshape(10, 5) # Array to be indexed
b = np.arange(9, -1, -2) # Indexing array
print (np.diagonal(a[b]))
# [45 36 27 18  9]

正如评论中提到的@user2357112,返回np.diagonal是只读的。在我看来,如果您打算将这些值附加/修改到这个最终所需的列表中,那将是一个问题。如果您只想打印它们或将它们用于进一步的索引,那应该没问题。

根据文档

从 NumPy 1.9 开始,它返回原始数组的只读视图。尝试写入结果数组将产生错误。

在未来的某个版本中,它将返回一个读/写视图,并且写入返回的数组将改变您的原始数组。返回的数组将与输入数组具有相同的类型。

如果您不写入此函数返回的数组,那么您可以忽略以上所有内容。


推荐阅读