【问题标题】:Boolean indexing array through array of boolean indexes without loop通过布尔索引数组的布尔索引数组,没有循环
【发布时间】:2019-06-13 13:52:53
【问题描述】:

我想通过多个布尔数组索引一个带有布尔掩码的数组,而无需循环。

这是我想要实现的,但没有循环,只有 numpy。

import numpy as np
a = np.array([[0, 1],[2, 3]])
b = np.array([[[1, 0], [1, 0]], [[0, 0], [1, 1]]], dtype=bool)

r = []
for x in b:
    print(a[x])
    r.extend(a[x])

# => array([0, 2])
# => array([2, 3])

print(r)
# => [0, 2, 2, 3]

# what I would like to do is something like this
r = some_fancy_indexing_magic_with_b_and_a
print(r)
# => [0, 2, 2, 3]

【问题讨论】:

    标签: python arrays numpy matrix-indexing


    【解决方案1】:

    方法#1

    使用np.broadcast_toa 广播到b's 形状,然后使用b 对其进行屏蔽-

    In [15]: np.broadcast_to(a,b.shape)[b]
    Out[15]: array([0, 2, 2, 3])
    

    方法 #2

    另一个是获取所有索引和 mod 大小为a,这也是b 中每个2D 块的大小,然后索引到扁平@ 987654330@-

    a.ravel()[np.flatnonzero(b)%a.size]
    

    方法#3

    在与 App#2 相同的行上,但保持 2D 格式并沿 b 的最后两个轴使用非零索引 -

    _,r,c = np.nonzero(b)
    out = a[r,c]
    

    大型阵列上的时序(给定放大 100 倍的样本形状)-

    In [50]: np.random.seed(0)
        ...: a = np.random.rand(200,200)
        ...: b = np.random.rand(200,200,200)>0.5
    
    In [51]: %timeit np.broadcast_to(a,b.shape)[b]
    45.5 ms ± 381 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)
    
    In [52]: %timeit a.ravel()[np.flatnonzero(b)%a.size]
    94.6 ms ± 1.64 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)
    
    In [53]: %%timeit
        ...: _,r,c = np.nonzero(b)
        ...: out = a[r,c]
    128 ms ± 1.46 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)
    

    【讨论】:

    • 在我的代码中我必须这样做:np.expand_dims(a, axis=-1)。我的 a 的形状现在是 (2, 3, 2),b 的形状是 (2, 3)
    • @SparkMonkay 因此,作为输入 - 数据数组 a3D 布尔数组/掩码 b2D?
    猜你喜欢
    • 1970-01-01
    • 2021-01-06
    • 2019-06-18
    • 2020-03-25
    • 2017-08-06
    • 2021-08-31
    • 2018-04-01
    • 1970-01-01
    • 2015-08-30
    相关资源
    最近更新 更多