【问题标题】:Making for loop with index arrays faster使用索引数组更快地进行 for 循环
【发布时间】:2015-03-21 03:26:48
【问题描述】:

我有以下问题:我有带有重复索引的索引数组,并且想向这样的数组添加值:

grid_array[xidx[:],yidx[:],zidx[:]] += data[:]

但是,由于我有重复的索引,这不起作用,因为 numpy 将创建一个临时数组,导致重复索引的数据被分配多次而不是相互添加(请参阅http://docs.scipy.org/doc/numpy/user/basics.indexing.html) .

类似的for循环

for i in range(0,n):
    grid_array[xidx[i],yidx[i],zidx[i]] += data[i]

会很慢。有没有办法我仍然可以使用 numpy 的矢量化?还是有其他方法可以更快地完成这项任务?

感谢您的帮助

【问题讨论】:

  • 你能举个例子来提问吗?
  • 重复是指某些索引对可以重复吗?所以你可能会得到grid_array(1,3,4) + data[3]+data[4}+data[10]
  • 没错,有些索引对会重复,就会出现你描述的情况。

标签: python arrays numpy


【解决方案1】:

使用 bincount 怎么样?

import numpy as np

flat_index = np.ravel_multi_index([xidx, yidx, zidx], grid_array.shape)
datasum = np.bincount(flat_index, data, minlength=grid_array.size)
grid_array += datasum.reshape(grid_array.shape)

【讨论】:

    【解决方案2】:

    这是一个缓冲问题。 .at 提供无缓冲操作 http://docs.scipy.org/doc/numpy/reference/generated/numpy.ufunc.at.html#numpy.ufunc.at

    np.add.at(grid_array, (xidx,yidx,zidx),data)
    

    【讨论】:

    • 感谢您让我意识到这一点。
    • 感谢您的出色回答。这对我帮助很大!而且我认为这个答案比目前接受的答案要好得多......事实上,如果我得到 >= 150 分,我会奖励你 50 作为赏金! :)
    【解决方案3】:

    要将数组添加到嵌套数组的元素中,您只需 grid_array[::]+=data

    >>> grid_array=np.array([[1,2,3],[4,5,6],[7,8,9]])
    >>> data=np.array([3,3,3])
    >>> grid_array[::]+=data
    >>> grid_array
    array([[ 4,  5,  6],
           [ 7,  8,  9],
           [10, 11, 12]])
    

    【讨论】:

    • 我认为这不是我想要的,我想将不同的数据添加到 3-D 数组中。
    【解决方案4】:

    我想我找到了一个可能的解决方案:

    def assign(xidx,yidx,zidx,data):
        grid_array[xidx,yidx,zidx] += data
        return
    
    map(assign,xidx,yidx,zidx,sn.part0['mass'])
    

    【讨论】:

    • map 只是隐藏了循环。
    • 我猜它的处理方式必须与 for 循环不同,因为它运行得更快。
    • 在我的小型测试中,各种循环结构的时间差异不大。
    • 使用 map 进行就地操作(通常称为副作用)是个坏主意。如果没有其他原因,你应该避免它,因为在 python3 中 map 返回一个生成器,你需要写 for item in map(assign,xidx,yidx,zidx,sn.part0['mass']): pass 这真的很难看。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-04-23
    • 2020-11-20
    • 1970-01-01
    • 2019-09-13
    • 1970-01-01
    • 2016-05-30
    • 2023-03-31
    相关资源
    最近更新 更多