在numpy数组外部进行索引时的默认值,即使使用非平凡索引也是如此

在numpy数组外部进行索引时的默认值,即使使用非平凡索引也是如此,numpy,indexoutofboundsexception,Numpy,Indexoutofboundsexception,是否可以在不抛出索引器的情况下从nd数组中查找条目 我希望有这样的东西: >>> a = np.arange(10) * 2 >>> a[[-4, 2, 8, 12]] IndexError >>> wrap(a, default=-1)[[-4, 2, 8, 12]] [-1, 4, 16, -1] >>> wrap(a, default=-1)[200] -1 或者可能更像get\u和\u default(a,[-4

是否可以在不抛出
索引器的情况下从nd数组中查找条目

我希望有这样的东西:

>>> a = np.arange(10) * 2
>>> a[[-4, 2, 8, 12]]
IndexError
>>> wrap(a, default=-1)[[-4, 2, 8, 12]]
[-1, 4, 16, -1]

>>> wrap(a, default=-1)[200]
-1
或者可能更像
get\u和\u default(a,[-4,2,8,12],default=-1)


有什么内在的方法可以做到这一点吗?我可以要求numpy不要抛出异常并返回垃圾,然后用我的默认值替换它吗?

np。使用
clip
模式执行此操作

In [155]: a
Out[155]: array([ 0,  2,  4,  6,  8, 10, 12, 14, 16, 18])

In [156]: a.take([-4,2,8,12],mode='raise')
...
IndexError: index 12 is out of bounds for size 10

In [157]: a.take([-4,2,8,12],mode='wrap')
Out[157]: array([12,  4, 16,  4])

In [158]: a.take([-4,2,8,12],mode='clip')
Out[158]: array([ 0,  4, 16, 18])
除了你对返回值没有太多的控制-这里索引12返回18,最后一个值。并将-4视为另一个方向的边界,返回0

添加默认值的一种方法是先填充
a

In [174]: a = np.arange(10) * 2
In [175]: ind=np.array([-4,2,8,12])

In [176]: np.pad(a, [1,1], 'constant', constant_values=-1).take(ind+1, mode='clip')
Out[176]: array([-1,  4, 16, -1])

不太漂亮,但这是一个开始。

您可以使用
np.maximum()
np.minimum()
将索引的范围限制为要索引的值数组的大小

例如:

我有一张像这样的热图

h = np.array([[ 2,  3,  1],
              [ 3, -1,  5]])
我有一个RGB值调色板,我想用来给热图上色。调色板仅为值0..4命名颜色:

p = np.array([[0, 0, 0],  # black
              [0, 0, 1],  # blue
              [1, 0, 1],  # purple
              [1, 1, 0],  # yellow
              [1, 1, 1]]) # white
现在,我想使用调色板为热图上色:

p[h]
目前,由于热图中的值
-1
5
,这会导致错误:

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
IndexError: index 5 is out of bounds for axis 0 with size 5
p[np.maximum(np.minimum(h, 4), 0)]
这是有效的,并给出了结果:

array([[[1, 0, 1],
        [1, 1, 0],
        [0, 0, 1]],

       [[1, 1, 0],
        [0, 0, 0],
        [1, 1, 1]]])
如果您确实需要为超出范围的索引指定一个特殊值,您可以像这样实现建议的
get\u with\u default()

def get_with_default(values, indexes, default=-1):
    return np.concatenate([[default], values, [default]])[
        np.maximum(np.minimum(indexes, len(values)), -1) + 1]

a = np.arange(10) * 2
get_with_default(a, [-4, 2, 8, 12], default=-1)
将返回:

array([-1,  4, 16, -1])

这是我在任何stack exchange网站上的第一篇帖子,请原谅我的任何风格错误(希望只有风格错误)。我对相同的功能感兴趣,但在numpy中找不到比hpaulj提到的np.take更好的功能。不过,np.take并不能完全满足需要。阿尔夫的答案是可行的,但需要一些细节来处理n维输入。下面是另一个适用于n维情况的变通方法。其基本思想与Alfe使用的类似:创建一个新索引,将越界索引屏蔽(在我的例子中)或伪装(在Alfe的例子中),并使用它对输入数组进行索引,而不会引发错误

def take(a,indices,default=0):
    #initialize mask; will broadcast to length of indices[0] in first iteration
    mask = True
    for i,ind in enumerate(indices):
        #each element of the mask is only True if all indices at that position are in bounds 
        mask = mask & (0 <= ind) & (ind < a.shape[i])
    #create in_bound indices
    in_bound = [ind[mask] for ind in indices]
    #initialize result with default value
    result = default * np.ones(len(mask),dtype=a.dtype)
    #set elements indexed by in_bound to their appropriate values in a
    result[mask] = a[tuple(in_bound)]
    return result

够近了,谢谢!用默认值填充周长就足以使其正常工作。嗯,
np.take
[]
使用的索引规则集不同。有没有一种简单的方法可以将像
np.s_1[2,3,4],:]
这样的东西转换成适合传递给take的对象?事实上,似乎np.take只适用于简单的情况。也许我应该使用2D数组作为例子,而不是我实际需要的是
arr.take(np.ravel\u multi\u index(key,dims=arr.shape,mode='clip'))
>>> a = np.arange(10)*2
>>> indices = (np.array([-4,2,8,12]),)
>>> take(a,indices,default=-1)
array([-1,  4, 16, -1])