【问题标题】:how do i change indexes in an array using numba如何使用 numba 更改数组中的索引
【发布时间】:2021-01-04 17:03:12
【问题描述】:

我有一个函数,我在其中执行一些操作,并想用 numba 加快它的速度。在我的代码中,使用高级索引更改数组中的值不起作用。我认为他们确实在 numba 文件中这么说。但是像 numpy.put() 这样的解决方法是什么?

这是我想做的一个简短的例子:

#example array
array([[ 0,  1,  2],
       [ 0,  2, -1],
       [ 0,  3, -1]])

使用 numba 中的任何方法更改给定索引处的值...以获得: 更改值:[0,0]、[1,2]、[2,1]

#changed example array by given indexes with one given value (10)
array([[ 10,  1,  2],
       [ 0,  2, 10],
       [ 0,  10, -1]])

这是我在 python 中所做的,但没有使用 numba:

indexList 是一个 Tuple,与 numpy.take() 配合使用

这是工作示例 python 代码,数组中的值更改为 100。

x = np.zeros((151,151))
print(x.ndim)
indexList=np.array([[0,1,3],[0,1,2]])
indexList=tuple(indexList)

def change(xx,filter_list):
    xx[filter_list] = 100
    return xx

Z = change(x,indexList)

现在在函数上使用@jit:

@jit
def change(xx,filter_list):
    xx[filter_list] = 100
    return xx

Z = change(x,indexList)

编译正在回退到启用循环提升的对象模式,因为函数“更改”失败了类型推断,原因是:找不到用于签名的函数 Function() 的实现:setitem(array(float64, 2d, C ), UniTuple(array(int32, 1d, C) x 2), Literalint)

出现此错误。所以我需要一个解决方法。 numba 不支持 numpy.put()。

如果有任何想法,我将不胜感激。

谢谢

【问题讨论】:

  • 为什么要使用numba进行这个操作?这是 numpy 操作的构建,即使 numba 对于较小的数组可能更快,但对于较大的数组,它几乎总是一样快...
  • 感谢您的回复!在我的示例中,此操作在每次迭代时在更大的 for 循环中发生大约 3 次。上面的代码只是一个例子,说明我想用 numba 做什么或什么不起作用。
  • 我在论坛上搜索了这个问题,但没有找到任何解决方案。仅关于我能找到的 numpy.take() 操作,但我需要它的反向操作。

标签: python arrays numpy indexing numba


【解决方案1】:

如果将indexList 保留为数组对您来说不是问题,您可以将其与change 函数中的for 循环结合使用,以使其与numba 兼容:

indexList = np.array([[0,1,3],[0,1,2]]).T

@njit()
def change(xx, filter_list):
    for y, x in filter_list:
        xx[y, x] = 100
    return xx
change(x, indexList)

请注意,indexList 必须经过转置才能使yx 坐标沿第一个轴。换句话说,它必须具有(n, 2) 而不是(2, n) 的形状,n 点才能改变。实际上它现在是一个坐标列表:[[0, 0],[1, 1],[3, 2]]

【讨论】:

  • 嗨,谢谢你 mandualaj!我接受了你的回答。我有一些不同的方法来解决我的问题,只是使用枚举。非常感谢。
【解决方案2】:

@mandulaj 发布了要走的路。在 mandulaj 给出答案之前,我采取了一种不同的方式。

使用此功能,我会收到弃用警告...所以最好使用 @mandulaj 并且不要忘记转置 indexList。

@jit
def change_arr(arr,idx,val): # change values in array by np index array to value
    for i,item in enumerate(idx):
        arr[item[0],item[1]]= val
    return arr

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-04-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-09
    • 2019-05-27
    相关资源
    最近更新 更多