Numpy数组:有效使用包含索引的数组

2024-04-26 00:20:38 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个工作和功能的python代码,但我不知道它是否可以更快。你知道吗

我们总共有四个相同形状的二维输入数组。其中三个数组包含整数(用作索引),另一个数组包含双精度。你知道吗

要优化的函数需要在包含数组的索引定义的位置将包含双精度数组的值添加到三维数组中。我的代码如下所示:

    array_3D[index_one, index_two, index_three] += array_with_doubles

所以问题是:这是一种有效的编程方式吗?我不确定,但我希望[]索引符号可以被高效的东西所取代。这个函数调用了很多次,占用了我执行时间的+-50%(根据snakevis)。你知道吗

另一种不同的策略是降低3D数组的维数,尽管我可以想象代码在可读性方面会损失很多。你知道吗


Tags: 函数代码功能index定义with精度整数
1条回答
网友
1楼 · 发布于 2024-04-26 00:20:38

更简单的2d案例:

In [48]: index1=np.array([1,1,2,2,3,3,4,4]);
     index2=np.array([0,2,1,2,3,4,4,5])
In [49]: data=np.arange(1,9)
In [50]: target=np.zeros((5,6))
In [53]: target[index1,index2]=data

In [54]: target
Out[54]: 
array([[ 0.,  0.,  0.,  0.,  0.,  0.],
       [ 1.,  0.,  2.,  0.,  0.,  0.],
       [ 0.,  3.,  4.,  0.,  0.,  0.],
       [ 0.,  0.,  0.,  5.,  6.,  0.],
       [ 0.,  0.,  0.,  0.,  7.,  8.]])

如果“ravel”索引,可以使用puttarget.flat

In [51]: flatindex=np.ravel_multi_index((index1,index2),target.shape)
In [52]: flatindex
Out[52]: array([ 6,  8, 13, 14, 21, 22, 28, 29], dtype=int32)
In [58]: np.put(target,flatindex,data)
In [61]: target.flat[flatindex]=data

一些快速时间比较(对于=data,而不是+=data):

In [63]: timeit target[index1,index2]=data
100000 loops, best of 3: 6.63 µs per loop

In [64]: timeit np.put(target,flatindex,data)
100000 loops, best of 3: 2.47 µs per loop

In [65]: timeit target.flat[flatindex]=data
100000 loops, best of 3: 2.77 µs per loop

In [66]: %%timeit
   ....: flatindex=np.ravel_multi_index((index1,index2),target.shape)
   ....: target.flat[flatindex]=data
   ....: 
100000 loops, best of 3: 7.34 µs per loop

target.flat[]=是赢家-如果raveled索引已经可用。如果对相同的索引数组重复应用此计算,则可能会出现这种情况。请记住,小阵列上的时间测试在大阵列上的伸缩性可能不同。你知道吗

+=代替,put不起作用。flat具有速度优势,即使必须计算ravel

In [78]: timeit target[index1,index2]+=data
100000 loops, best of 3: 16.2 µs per loop

In [79]: timeit target.flat[flatindex]+=data
100000 loops, best of 3: 7.45 µs per loop

In [80]: %%timeit                          
flatindex=np.ravel_multi_index((index1,index2),target.shape)
target.flat[flatindex]+=data
   ....: 
100000 loops, best of 3: 13.4 µs per loop

但是-如果索引有重复,并且您希望添加所有data值,那么问题会发生显著变化。像这样的直接索引使用缓冲,所以只有最后添加的一个点才适用。你知道吗

有关缓冲问题和替代方案的讨论,请参阅最近的SO问题

Vector operations with numpy

相关问题 更多 >