【问题标题】:Numpy 2D array indexing without out of bound and with clipping valueNumpy 2D 数组索引没有越界和裁剪值
【发布时间】:2017-02-07 19:30:09
【问题描述】:

我有索引数组

a = np.array([
   [0, 0],
   [1, 1],
   [1, 9]
])

二维数组

b = np.array([
   [0, 1, 2, 3],
   [5, 6, 7, 8]
])

我能做到这一点

b[a[:, 0], a[:, 1]]

但这将是一个例外“超出范围”,因为 9 超出范围。 我需要一种非常快速的方法来按索引制作数组切片,如果我可以设置剪辑值,那将是理想的,例如:

np.indexing_with_clipping(array=b, indices=a, clipping_value=0)
> array([0, 6, --> 0 = clipped value <--])

【问题讨论】:

    标签: python arrays numpy multidimensional-array


    【解决方案1】:

    这是一种方法-

    def indexing_with_clipping(arr, indices, clipping_value=0):
        idx = np.where(indices < arr.shape,indices,clipping_value)
        return arr[idx[:, 0], idx[:, 1]]
    

    示例运行 -

    In [266]: arr
    Out[266]: 
    array([[0, 1, 2, 3],
           [5, 6, 7, 8]])
    
    In [267]: indices
    Out[267]: 
    array([[0, 0],
           [1, 1],
           [1, 9]])
    
    In [268]: indexing_with_clipping(arr,indices,clipping_value=0)
    Out[268]: array([0, 6, 5])
    
    In [269]: indexing_with_clipping(arr,indices,clipping_value=1)
    Out[269]: array([0, 6, 6])
    
    In [270]: indexing_with_clipping(arr,indices,clipping_value=2)
    Out[270]: array([0, 6, 7])
    
    In [271]: indexing_with_clipping(arr,indices,clipping_value=3)
    Out[271]: array([0, 6, 8])
    

    关注内存和性能效率,这是一种修改函数内索引的方法 -

    def indexing_with_clipping_v2(arr, indices, clipping_value=0):
        indices[indices >= arr.shape] = clipping_value
        return arr[indices[:, 0], indices[:, 1]]
    

    示例运行 -

    In [307]: arr
    Out[307]: 
    array([[0, 1, 2, 3],
           [5, 6, 7, 8]])
    
    In [308]: indices
    Out[308]: 
    array([[0, 0],
           [1, 1],
           [1, 9]])
    
    In [309]: indexing_with_clipping_v2(arr,indices,clipping_value=2)
    Out[309]: array([0, 6, 7])
    

    【讨论】:

    • np.take 怎么样?
    • 谢谢你的回答,但是这个“np.where(indices
    • @hpaulj 是的,我知道 np.take,但有两个问题:1)没有裁剪值,2)只有一维数组...
    • @MaxTkachenko 你介意原始索引数组a在函数内被修改吗?
    • @MaxTkachenko 另外,ab 在您的实际用例中的典型形状是什么?
    【解决方案2】:

    您可以使用列表推导:

    b[
        [min(x,len(b[0])-1) for x in a[:,0]],
        [min(x,len(b[1])-1) for x in a[:,1]]
    ]
    

    edit我使用最后一个数组值作为您的裁剪值,但您可以将min() 函数替换为您想要的任何值(例如三元运算符)

    edit2 好的,基于 cmets 中的说明以及我可以放在一起的所有 python-fu,这个片段最终可以满足您的需要:

    clipping_value = -1
    tmp=np.append(b,[[clipping_value],[clipping_value]],axis=1)
    tmp[zip(*[((x,y) if (x<b.shape[0] and y<b.shape[1]) else (0,b.shape[1])) for (x,y) in zip(a.transpose()[0],a.transpose()[1])])]
    

    与上面相同,只是创建 ndarray tmp,它是 b 的副本,但包含 clipping_value 作为其最后一个元素,然后使用我以前的解决方案设置索引,以便它们指向如果任一索引大于b 的维度,则为最后一个元素。

    我了解到zip 函数存在相反的情况,并且 numpy 数组接受列表作为索引。好玩。谢谢。

    【讨论】:

    • 我认为这不是坏主意,np.clip() 在这里是更快的解决方案。谢谢:)
    • @MaxTkachenko 但是.clip()不会让你设置clipping_value,对吧?
    • @Divakar 我的意思是使用 np.clip() 而不是 [min(x,len(b[0])-1) for x in a[:,0]] 以避免慢“为”。
    • @MaxTkachenko 我现在看到了你的问题,我的方法只允许你从原始数组中选择一个值,剪辑确实会更快。
    • @MaxTkachenko 查看我的最新编辑。这是你需要的吗?
    猜你喜欢
    • 1970-01-01
    • 2013-07-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多