Numpy 2D数组索引没有超出限制和剪切值

时间:2016-09-29 12:51:43

标签: python arrays numpy multidimensional-array

我有索引数组

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

和二维数组

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

我可以做到这一次

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

但它会是一个例外'越界',因为9超出范围。 我需要一个非常快的方式来通过索引进行数组切片,如果我可以设置一个剪辑值,它将是理想的,例如:

{{1}}

2 个答案:

答案 0 :(得分: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])

答案 1 :(得分:1)

您可以使用列表理解:

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

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

edit2 好的,根据评论中的说明和我可以放在一起的所有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数组接受列表作为索引。好玩。感谢。