Python 访问numpy数组的段

Python 访问numpy数组的段,python,numpy,Python,Numpy,我有数据 A = np.array([1,2,3,4,5,6,7,8,9,10]) ind = np.array([0,1,4]) beg = 3 A和ind的典型规模为数百万 我想做的是用索引ind+beg修改A中的数据 for i in range(0,ind.size): A[ind[i]+beg] += 1 由于对A(+1)的操作与将beg添加到ind[i]几乎相同, 我想避免这种情况 在C代码中,我通常使用指针来实现这一点 int* ptA = A-beg; for(int

我有数据

A = np.array([1,2,3,4,5,6,7,8,9,10])
ind = np.array([0,1,4])
beg = 3
A
ind
的典型规模为数百万

我想做的是用索引
ind+beg
修改
A
中的数据

for i in range(0,ind.size):
    A[ind[i]+beg] += 1
由于对
A
+1
)的操作与将
beg
添加到
ind[i]
几乎相同, 我想避免这种情况

在C代码中,我通常使用指针来实现这一点

int* ptA = A-beg;
for(int i=0; i<indsize; i++) ptA[ind[i]]++;
int*ptA=A-beg;

for(int i=0;iNumpy具有强大的索引功能,如下所示:

在您的情况下,您可以:

>>> A[ind+beg] += 1

这将向
ind
的每个成员添加
beg
,然后在这些位置索引到
A
,并递增。

Numpy具有强大的索引功能,如下所示:

在您的情况下,您可以:

>>> A[ind+beg] += 1

这将向
ind
的每个成员添加
beg
,然后在这些位置索引到
A
,并递增。

我认为与
C
方法相当的是:
A[beg:[ind]+=1
,它保存了一些添加。
add.at
是一个无缓冲版本,如果
ind
有 重复值。通常速度较慢

A=arange(10010)
ind=np.unique(randint(0,10000,1000))
beg = 3

In [236]: %timeit for i in range(0,ind.size): A[ind[i]+beg] += 1
3.01 ms ± 313 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

In [237]: %timeit A[beg+ind]+=1
39.8 µs ± 5.39 µs per loop (mean ± std. dev. of 7 runs, 10000 loops each)

In [238]: %timeit A[beg:][ind]+=1
33.3 µs ± 2.6 µs per loop (mean ± std. dev. of 7 runs, 10000 loops each)

In [239]: %timeit add.at(A[beg:],ind,1)
151 µs ± 10.2 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)    
Numba
Cython
可以进一步加快此操作:

@numba.njit
def addat(A,beg,ind,amount):
    u=A[beg:]
    for i in ind:
        u[i]+=amount

In [249]: %timeit addat(A,beg,ind,1)
3.13 µs ± 688 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)

我认为你的
C
方法的等价物是:
A[beg:[ind]+=1
,它节省了一些添加。
add.at
是一个无缓冲版本,如果
ind
有 重复值。通常速度较慢

A=arange(10010)
ind=np.unique(randint(0,10000,1000))
beg = 3

In [236]: %timeit for i in range(0,ind.size): A[ind[i]+beg] += 1
3.01 ms ± 313 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

In [237]: %timeit A[beg+ind]+=1
39.8 µs ± 5.39 µs per loop (mean ± std. dev. of 7 runs, 10000 loops each)

In [238]: %timeit A[beg:][ind]+=1
33.3 µs ± 2.6 µs per loop (mean ± std. dev. of 7 runs, 10000 loops each)

In [239]: %timeit add.at(A[beg:],ind,1)
151 µs ± 10.2 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)    
Numba
Cython
可以进一步加快此操作:

@numba.njit
def addat(A,beg,ind,amount):
    u=A[beg:]
    for i in ind:
        u[i]+=amount

In [249]: %timeit addat(A,beg,ind,1)
3.13 µs ± 688 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)

令人惊讶的是,在自己测试时,这似乎是最快的答案!我想知道为什么。令人惊讶的是,在自己测试时,这似乎是最快的答案!我想知道为什么。