【问题标题】:Broadcast advanced indexing numpy广播高级索引numpy
【发布时间】:2015-06-25 02:11:48
【问题描述】:

例如,我有一个值数组

x = array([[[-0.78867513, -0.21132487,  0.        ,  0.78867513,  0.21132487,    0.        ,  0.        ,  0.        ,  0.        ],
            [ 0.        , -0.78867513, -0.21132487,  0.        ,  0.78867513,    0.21132487,  0.        ,  0.        ,  0.        ],
            [ 0.        ,  0.        ,  0.        , -0.78867513, -0.21132487,    0.        ,  0.78867513,  0.21132487,  0.        ],
            [ 0.        ,  0.        ,  0.        ,  0.        , -0.78867513,   -0.21132487,  0.        ,  0.78867513,  0.21132487]],
           [[-0.78867513, -0.21132487,  0.        ,  0.78867513,  0.21132487,    0.        ,  0.        ,  0.        ,  0.        ],
            [ 0.        , -0.78867513, -0.21132487,  0.        ,  0.78867513,    0.21132487,  0.        ,  0.        ,  0.        ],
            [ 0.        ,  0.        ,  0.        , -0.78867513, -0.21132487,    0.        ,  0.78867513,  0.21132487,  0.        ],
            [ 0.        ,  0.        ,  0.        ,  0.        , -0.78867513,   -0.21132487,  0.        ,  0.78867513,  0.21132487]]])

我想使用高级索引来提取非零值。我知道非零值的索引所以

idx = array([[4, 3, 1, 0],
             [5, 4, 2, 1],
             [7, 6, 4, 3],
             [8, 7, 5, 4]])

想要的结果是这样的

x[idx] = array([[[-0.78867513, -0.21132487,  0.78867513,  0.21132487],
                 [-0.78867513, -0.21132487,  0.78867513,  0.21132487],
                 [-0.78867513, -0.21132487,  0.78867513,  0.21132487],
                 [-0.78867513, -0.21132487,  0.78867513,  0.21132487]],
                [[-0.78867513, -0.21132487,  0.78867513,  0.21132487],
                 [-0.78867513, -0.21132487,  0.78867513,  0.21132487],
                 [-0.78867513, -0.21132487,  0.78867513,  0.21132487],
                 [-0.78867513, -0.21132487,  0.78867513,  0.21132487]]])

实际的x 数组沿第一维要大得多,但非零结构始终由idx 指示,因此我需要它沿第一维广播。这可能吗?

编辑:要清楚x 沿第一个维度包含4 x 9 数组的嵌套列表。 idx 然后逐行包含非零条目。注意x 中两个4 x 9 嵌套数组的第一行4 3 1 0 条目不为零。

【问题讨论】:

  • 尚不清楚idx 与哪些元素非零相关。
  • 添加和编辑澄清。
  • 元素沿idx第二轴的顺序有什么意义吗?我本来希望您所需输出的元素以不同的顺序排列。另外,是否保证x 的结构不会使idx 呈锯齿状?
  • 是的,它们应该是有序的,所以 +/- 符号应该有变化。抱歉弄错了
  • 另外,idx 永远不会是锯齿状的,永远是矩形的。

标签: python numpy


【解决方案1】:

试试这个:

x[:,np.arange(idx.shape[0])[:,None],idx]

使用这种技术,np.arange(idx.shape[0])[:,None] 中的每个元素(其形状为 (idx.shape[0], 1),因此是一个列向量)将与 idx 中的每一行一起广播。这将用于沿 x 的第一个轴的所有条目。

【讨论】:

    【解决方案2】:

    我为您的问题尝试了这个班轮,它似乎不需要idx就可以完成这项工作。您可能需要根据问题的大小更改.reshape() 中的参数。

    np.array(filter(lambda x: x!=0, x.ravel())).reshape(-1, 4, 4)
    

    它将数组展平,删除零,然后将其更改回所需的形状。

    这是另一个可能更高效的版本,因为它不使用 filter 函数而是使用 布尔索引 代替 numpy 数组

    y = x.ravel()
    z = y[y!=0].reshape(-1, 4, 4)
    

    编辑:

    在玩 numpy 时,我发现了另一种方法。

    x[x!=0].reshape(-1, 4, 4)
    

    这是所有三种方法的性能:

    • 方法一:10000 loops, best of 3: 21.2 µs per loop
    • 方法二:100000 loops, best of 3: 2.42 µs per loop
    • 方法三:100000 loops, best of 3: 1.97 µs per loop

    【讨论】:

    • 我很想看看是否像我之前的帖子中那样将转换为布尔值,并进行展平和重塑,是否与 x!=0 方法一样快或更快,后者涉及不同类型的比较我想。
    • @MikeO'Connor 我尝试分析你的第二种方法,它几乎是一样的。这是我得到的100000 loops, best of 3: 2.35 µs per loop
    • 非常感谢 Lakshay Gang...我在想,也许选角比 x!=0 比较好。
    【解决方案3】:

    好吧,这有点奇怪,但这里是……

    idxes = np.ones((x.shape[0], x.shape[1], 1), dtype=bool) * idx
    print x[np.array(x, dtype=bool)].reshape(idxes.shape)
    

    当然你必须记住写np.array而不是array

    干杯!

    您可以通过以下方式减轻计算 idx 的负担:

    y = x[np.array(x, dtype=bool)]
    print y.reshape(x.shape[0], x.shape[1], y.size/x.shape[0]/x.shape[1])
    

    有了这个或上面的行,将浮点数转换为布尔值,提供一个消除零的掩码。

    【讨论】:

      猜你喜欢
      • 2020-10-11
      • 1970-01-01
      • 1970-01-01
      • 2017-03-18
      • 2017-12-28
      • 1970-01-01
      • 2018-12-23
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多