简体   繁体   English

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

[英]Numpy 2D array indexing without out of bound and with clipping value

I have indices array 我有索引数组

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

And 2D array 和2D阵列

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

I can do this one 我可以做到这一点

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

But it'll be an exception ' out of bounds ', because 9 is out of range. 但这将是一个例外' 超出范围 ',因为9超出范围。 I need a very fast way to make array slice by indices and it will be ideal if I can set a clip value, eg: 我需要一种非常快速的方法来通过索引进行数组切片,如果我可以设置一个剪辑值,它将是理想的,例如:

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

Here's an approach - 这是一种方法 -

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

Sample runs - 样品运行 -

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])

With focus on memory and performance efficiency, here's an approach that modifies the indices within the function - 关注内存和性能效率,这是一种修改函数内索引的方法 -

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

Sample run - 样品运行 -

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])

You can use list comprehension: 您可以使用列表理解:

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

edit I used last array value as your clipping value, but you can replace the min() function with whatever you want (eg trenary operator) 编辑我使用最后一个数组值作为剪切值,但您可以将min()函数替换为您想要的任何值(例如trenary运算符)

edit2 OK, based on clarification in comments and all python-fu that I could put together, this snipped finally does what you need: 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])])]

It is the same as above, just creates ndarray tmp , which is a copy of b but contains the clipping_value as its last element and then uses my previous solution to set indices so, that they point to the last element if either of the indices is bigger than dimensions of b . 它与上面相同,只是创建ndarray tmp ,它是b的副本,但是包含clipping_value作为它的最后一个元素,然后使用我之前的解决方案来设置索引,以便它们指向最后一个元素,如果其中一个索引是大于b尺寸。

I learned that there is reverse to the zip function and that the numpy arrays accept lists as indices. 我了解到zip函数有反向,numpy数组接受列表作为索引。 It was fun. 好玩。 Thanks. 谢谢。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM