2011-09-19 8 views
3

가정하자 I는 I 인덱스 쌍의 시리즈가 배열 A.이 (A1, B1), (A2, B2) (AN, BN)NumPy와 합

나는 그 쌍들 사이의 모든 원소의 합을 얻고 싶다. 즉

sum(A[a1:b1]), sum(A[a2:b2]), sum(A[a3:b3]) ... 

런타임면에서 가장 효율적인 방법은 무엇입니까?

감사합니다.

답변

8

(a,b) 범위가 겹치는 경향이 있는지, 인덱스의 많은 쌍 당신이 얻을 것으로 예상하는 방법 A의 크기에 대한 자세한 알려 색인을 가정하십시오 여기

c = numpy.r_[0, A.cumsum()][indices] 
sums = c[:,1] - c[:,0] 
+1

아주 좋은 ... :) – unutbu

+0

감사합니다. 덕분에 많은 도움이되었습니다. – Plamen

0

색인 쌍이 많고 배열이 긴 경우 캐싱이 옵션 일 수 있습니다.

CACHE = {} 
def mysum(a, b): 
    if (a, b) in CACHE: 
     return CACHE[(a, b)] 

    if a >= b: 
     return 0 

    s = A[a] + mysum(a+1, b) 
    CACHE[(a, b)] = s 
    return s 

같은 재귀 적 접근 방법을 시도해 보겠습니다. 그러나 정확성이나 효율성은 확인하지 않았습니다. 상위 지수 인 b을 줄이는 것도 사용할 수 있습니다.

0

첫 번째 인스턴스에서 내가 직접 해결 방법을 시도해보십시오 것 : ab 쌍의 순서입니다

[np.sum(A[a:b]) for (a,b) in ab] 

.

A[a:b]은 배열에 대한보기를 만듭니다. 거기에 관련된 데이터의 복사가 없습니다.

이 너무 느린 것으로 판명 경우 등

0

또 다른 방법 :

쌍 모양 (n, 2)nindices이 상당히 큰하는 NumPy와 배열에 포함됩니다, 그것은 어떤 파이썬 루프를 방지하기 위해 아마도 가장 좋습니다
 
a = np.random.rand(3000) 
indices = np.array([[0,3], [9,20], [5,30], [9,33]]) 
sums = np.add.reduceat(a, indices.ravel())[::2] 

assert np.all(sums == np.array([a[i:j].sum() for i,j in indices])) 

많은 인덱스가있는 경우 위의 cumsum은 아마 더 효율적입니다.