我有索引数组
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}}
答案 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数组接受列表作为索引。好玩。感谢。