【问题标题】:get a vector from a matrix and a vactor of index in numpy从矩阵中获取向量和numpy中的索引向量
【发布时间】:2021-03-20 02:11:01
【问题描述】:

我有一个矩阵 m = [[1,2,3],[4,5,6],[7,8,9]] 和一个向量 v=[1,2,0],其中包含我要为矩阵的每一列返回的行的索引。

我期望的结果应该是r=[4,8,3],但是我不知道如何使用 numpy 得到这个结果。

通过将向量应用于索引,对于每一列,我都会得到:m[v,[0,1,2]] = [4, 8, 3],这大致是我的任务。

为了防止硬编码列,我使用np.arange(m.shape[1]),我的最终公式看起来像r=m[v,np.arange(m.shape[1])]

这对我来说听起来很奇怪,对于应该很常见的事情来说有点复杂。

有没有一种干净的方法可以得到这样的结果?

【问题讨论】:

  • 我看不出使用 arange 有什么问题。那是advanced indexing,其中broadcasts 数组相互对抗以选择项目。虽然符号有点混乱,但这个概念非常笼统和强大。 MATLAB 需要使用 sub2ind 来生成类似的索引。

标签: python arrays numpy indexing indices


【解决方案1】:

正如numpy documentation 所说,我认为您提到的方式是执行此任务的标准方式:

示例
应从每一行中选择一个特定元素。行索引只是 [0, 1, 2],列索引指定要为相应行选择的元素,这里是 [0, 1, 0]。将两者结合使用,可以使用高级索引来解决任务:

x = np.array([[1, 2], [3, 4], [5, 6]])
x[[0, 1, 2], [0, 1, 0]]

【讨论】:

    【解决方案2】:
    In [157]: m = np.array([[1,2,3],[4,5,6],[7,8,9]]);v=np.array([1,2,0])
    In [158]: m
    Out[158]: 
    array([[1, 2, 3],
           [4, 5, 6],
           [7, 8, 9]])
    In [159]: v
    Out[159]: array([1, 2, 0])
    In [160]: m[v,np.arange(3)]
    Out[160]: array([4, 8, 3])
    

    我们选择 3 个元素,索引为 (1,0),(2,1),(0,2)。

    更接近 MATLAB 方法:

    In [162]: np.ravel_multi_index((v,np.arange(3)),(3,3))
    Out[162]: array([3, 7, 2])
    In [163]: m.flat[_]
    Out[163]: array([4, 8, 3])
    

    Octave/MATLAB 等效

    >> m = [1 2 3;4 5 6;7 8 9];
    >> v = [2 3 1]
    v =
    
       2   3   1
    
    >> m = [1 2 3;4 5 6;7 8 9];
    >> v = [2 3 1];
    >> sub2ind([3,3],v,[1 2 3])
    ans =
    
       2   6   7
    
    >> m(sub2ind([3,3],v,[1 2 3]))
    ans =
    
       4   8   3
    

    相同的broadcasting 用于访问块,如最近的问题所示:

    Is there a way in Python to get a sub matrix as in Matlab?

    【讨论】:

    • 别忘了np.take_along_axis!尽管必须明确地将 vm 进行广播会有点麻烦,但一旦这样做,它的可读性会更高。
    【解决方案3】:

    嗯,在 Integer array andexing 的文档中,这个“奇怪/复杂”的事情实际上被称为“直截了当”的场景,这是更广泛的“高级索引”主题下的一个子主题。

    引用一些摘录:

    当索引包含的整数数组数量与所要的数组一样多时 indexed 有维度,索引是直截了当的,但是 不同于切片。高级索引始终作为一个广播和迭代。请注意,结果形状与(广播)索引数组形状相同 块引用

    如果它看起来不那么复杂/奇怪,您可以使用range(m.shape[1]) 而不是np.arange(m.shape[1])。它只需要是任何数组或类似数组的结构。

    可视化/直觉:

    当我学习这个(整数数组索引)时,它帮助我通过以下方式可视化事物:

    我想象了并排放置的索引数组,它们都具有完全相同的形状(可能是一起广播的结果)。我还可视化了结果数组,它也具有与索引数组相同的形状。在每个索引数组和结果数组中,我想象了一只猴子,它能够遍历自己的数组,跳到自己数组的连续元素。请注意,一般来说,索引数组和结果数组的这种相同形状可以是 n 维的,并且这种相同的形状可能与值实际被索引的源数组的形状有很大不同。

    在您自己的示例中,源数组m 的形状为(3,3),索引数组和结果数组的形状均为(3,)

    在您的示例中,这三个数组(两个索引数组和结果数组)中的每一个都有一只猴子。然后我们可视化猴子串联遍历它们各自的数组元素。这里,“串联”意味着所有三只猴子都从各自数组的第一个元素开始,每当一只猴子跳到自己数组的下一个元素时,其他数组中的其他猴子也会跳到他们数组的下一个元素各自的数组。当它跳到每个连续的元素时,每个索引数组中的猴子都会调用它刚刚访问过的元素的值。所以两个索引数组中的两只猴子在各自的索引数组中读出了它们刚刚访问过的值。 结果数组中的猴子也与索引数组中的猴子一起跳跃。它听到猴子在索引数组中调用的值,使用这些值作为源数组的索引m,从而确定要从源数组m 中选取的值。结果数组中的猴子从源数组m 中获取该值,并将该值存储在结果数组中它刚刚跳到的位置。因此,例如,当所有三只猴子都在各自数组的第二个元素中时,结果数组的第二个位置将确定其值。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-02-27
      • 2017-11-18
      • 2016-06-13
      • 2023-01-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多