【问题标题】:Python - numpy : 'dimension dependent indexing'Python - numpy:'维度相关索引'
【发布时间】:2016-02-21 15:00:48
【问题描述】:

我正在为以下问题寻求一种优雅(且快速)的解决方案,简化更重的实际情况。答案可能在 numpy 以外的其他地方,我搜索了又搜索了......

所以,假设,我

a = np.array([[2,7],
              [3,6],
              [2,8]])

让我们拿一个假数据集:

b = np.random.random((3,10))

数组 a 中的行表示 b 的每一行中感兴趣的子集的较低和较高索引:“从 b 的第一行,我对子集 [2:7] 感兴趣,从第二行我” m 对子集 [3:6] 感兴趣,从第三行和最后一行开始对子集 [2:8] 感兴趣。”

我现在的想法是创建一种掩码数组 c

c = np.array([0,0,1,1,1,1,1,1,0,0],
              [0,0,0,1,1,1,1,0,0,0],
              [0,0,1,1,1,1,1,1,1,0]])

然后我继续工作

d = b*c

而我不感兴趣的元素现在是 0。

  • 如何使用 a 中的索引生成 c?
  • 您有更好的好主意吗?

正确的掩码数组,np.ix_,扭曲的 np.einsum,我找不到任何用于此目的的东西。当然,重点是避免循环,在我的脚本可见部分的列表中。但最终它甚至可以避免吗?

非常感谢!

【问题讨论】:

    标签: python arrays performance numpy vectorization


    【解决方案1】:

    您可以使用broadcasting 创建掩码 -

    n = b.shape[1]
    mask = (np.arange(n) >= a[:,None,0]) & (np.arange(n) <= a[:,None,1])
    d = mask*b
    

    示例运行 -

    In [252]: a
    Out[252]: 
    array([[2, 4],
           [3, 6],
           [2, 3]])
    
    In [253]: b
    Out[253]: 
    array([[908, 867, 917, 649, 758, 950, 692],
           [715, 745, 797, 595, 377, 421, 712],
           [213, 143, 169, 825, 858, 780, 176]])
    
    In [254]: n = b.shape[1]
         ...: mask = (np.arange(n) >= a[:,None,0]) & (np.arange(n) <= a[:,None,1])
         ...: 
    
    In [255]: mask
    Out[255]: 
    array([[False, False,  True,  True,  True, False, False],
           [False, False, False,  True,  True,  True,  True],
           [False, False,  True,  True, False, False, False]], dtype=bool)
    
    In [256]: mask*b
    Out[256]: 
    array([[  0,   0, 917, 649, 758,   0,   0],
           [  0,   0,   0, 595, 377, 421, 712],
           [  0,   0, 169, 825,   0,   0,   0]])
    

    【讨论】:

    • "..这样循环发生在 C 而不是 Python 中。" .广播!总是听说过它,总是想“我有点用它,对吧?”。这就是我一直在寻找的魔法,感谢 Divakar。大多数时候,您需要解决自己的示例才能真正理解新事物。
    • @Etienne 是的,大多数时候提问者都会发布简单的数据,我会在最后更改这些数据以测试所有可能的场景:) 是的,NumPy 通过一次性完成所有事情而不是参与来获得优化本身在循环中,在底层这些向量化操作是在 C 中完成的。
    猜你喜欢
    • 2017-12-31
    • 1970-01-01
    • 2012-02-03
    • 2016-04-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-07-26
    相关资源
    最近更新 更多