목록에서 숫자의 누적 합계를 찾는 방법은 무엇입니까?
time_interval = [4, 6, 12]
[4, 4+6, 4+6+12]
목록을 얻기 위해 같은 숫자를 요약하고 싶습니다 t = [4, 10, 22]
.
다음을 시도했습니다.
for i in time_interval:
t1 = time_interval[0]
t2 = time_interval[1] + t1
t3 = time_interval[2] + t2
print(t1, t2, t3)
4 10 22
4 10 22
4 10 22
이와 같은 배열로 많은 수치 작업을 수행하는 경우 numpy
누적 합계 함수와 함께 제공되는을 제안 합니다 cumsum
.
import numpy as np
a = [4,6,12]
np.cumsum(a)
#array([4, 10, 22])
Numpy는 종종 이런 종류의 경우 순수한 파이썬보다 빠릅니다 . @Ashwini의accumu
다음 과 비교하여보십시오 .
In [136]: timeit list(accumu(range(1000)))
10000 loops, best of 3: 161 us per loop
In [137]: timeit list(accumu(xrange(1000)))
10000 loops, best of 3: 147 us per loop
In [138]: timeit np.cumsum(np.arange(1000))
100000 loops, best of 3: 10.1 us per loop
그러나 물론 그것이 당신이 numpy를 사용할 유일한 곳이라면 그것에 의존 할 가치가 없을 수도 있습니다.
Python 2에서는 다음과 같이 고유 한 생성기 함수를 정의 할 수 있습니다.
def accumu(lis):
total = 0
for x in lis:
total += x
yield total
In [4]: list(accumu([4,6,12]))
Out[4]: [4, 10, 22]
그리고 Python 3.2 이상에서는 다음을 사용할 수 있습니다 itertools.accumulate()
.
In [1]: lis = [4,6,12]
In [2]: from itertools import accumulate
In [3]: list(accumulate(lis))
Out[3]: [4, 10, 22]
보다:
a = [4, 6, 12]
reduce(lambda c, x: c + [c[-1] + x], a, [0])[1:]
예상대로 출력됩니다.
[4, 10, 22]
파이썬 3.4과 상단이 답변의 벤치 마크를했고 나는 발견 itertools.accumulate
빨리보다 numpy.cumsum
종종 더 빨리, 많은 상황에서. 그러나 의견에서 알 수 있듯이 항상 그런 것은 아니며 모든 옵션을 철저히 탐색하기가 어렵습니다. (관심있는 벤치 마크 결과가 더 있으면 의견을 추가하거나이 게시물을 편집하십시오.)
일부 타이밍 ...
짧은 목록의 accumulate
경우 약 4 배 더 빠릅니다.
from timeit import timeit
def sum1(l):
from itertools import accumulate
return list(accumulate(l))
def sum2(l):
from numpy import cumsum
return list(cumsum(l))
l = [1, 2, 3, 4, 5]
timeit(lambda: sum1(l), number=100000)
# 0.4243644131347537
timeit(lambda: sum2(l), number=100000)
# 1.7077815784141421
긴 목록의 accumulate
경우 약 3 배 더 빠릅니다.
l = [1, 2, 3, 4, 5]*1000
timeit(lambda: sum1(l), number=100000)
# 19.174508565105498
timeit(lambda: sum2(l), number=100000)
# 61.871223849244416
이 경우 numpy
array
에 캐스팅되지 list
, accumulate
빠른 2 회에 대해 여전히 :
from timeit import timeit
def sum1(l):
from itertools import accumulate
return list(accumulate(l))
def sum2(l):
from numpy import cumsum
return cumsum(l)
l = [1, 2, 3, 4, 5]*1000
print(timeit(lambda: sum1(l), number=100000))
# 19.18597290944308
print(timeit(lambda: sum2(l), number=100000))
# 37.759664884768426
당신은이 개 기능으로 외부의 수입을 놓고 여전히 돌아 가면 numpy
array
, accumulate
거의 2 배 빠른 여전히 :
from timeit import timeit
from itertools import accumulate
from numpy import cumsum
def sum1(l):
return list(accumulate(l))
def sum2(l):
return cumsum(l)
l = [1, 2, 3, 4, 5]*1000
timeit(lambda: sum1(l), number=100000)
# 19.042188624851406
timeit(lambda: sum2(l), number=100000)
# 35.17324400227517
values = [4, 6, 12]
total = 0
sums = []
for v in values:
total = total + v
sums.append(total)
print 'Values: ', values
print 'Sums: ', sums
이 코드를 실행하면
Values: [4, 6, 12]
Sums: [4, 10, 22]
먼저 실행중인 하위 시퀀스 목록이 필요합니다.
subseqs = (seq[:i] for i in range(1, len(seq)+1))
그런 다음 sum
각 하위 시퀀스를 호출 합니다.
sums = [sum(subseq) for subseq in subseqs]
(모든 접두사를 반복적으로 추가하기 때문에 이것이 가장 효율적인 방법은 아닙니다.하지만 대부분의 사용 사례에서는 중요하지 않을 것이며 생각할 필요가 없다면 이해하기 더 쉽습니다. 누계.)
Python 3.2 이상을 사용 itertools.accumulate
하는 경우 다음을 사용 하여 수행 할 수 있습니다.
sums = itertools.accumulate(seq)
이전 3.1을 사용하거나하는 경우, 당신은 곧바로 워드 프로세서의 (변경을 제외하고 소스 "에 해당하는"를 그냥 복사 할 수 있습니다 next(it)
에 it.next()
2.5 및 이전 버전에 대한).
2.7에서 numpy가 작동하지 않는 파이썬 방식을 원한다면 이것이 내 방식 일 것입니다.
l = [1,2,3,4]
_d={-1:0}
cumsum=[_d.setdefault(idx, _d[idx-1]+item) for idx,item in enumerate(l)]
이제 시도해보고 다른 모든 구현에 대해 테스트 해 보겠습니다.
import timeit
L=range(10000)
def sum1(l):
cumsum=[]
total = 0
for v in l:
total += v
cumsum.append(total)
return cumsum
def sum2(l):
import numpy as np
return list(np.cumsum(l))
def sum3(l):
return [sum(l[:i+1]) for i in xrange(len(l))]
def sum4(l):
return reduce(lambda c, x: c + [c[-1] + x], l, [0])[1:]
def this_implementation(l):
_d={-1:0}
return [_d.setdefault(idx, _d[idx-1]+item) for idx,item in enumerate(l)]
# sanity check
sum1(L)==sum2(L)==sum3(L)==sum4(L)==this_implementation(L)
>>> True
# PERFORMANCE TEST
timeit.timeit('sum1(L)','from __main__ import sum1,sum2,sum3,sum4,this_implementation,L', number=100)/100.
>>> 0.001018061637878418
timeit.timeit('sum2(L)','from __main__ import sum1,sum2,sum3,sum4,this_implementation,L', number=100)/100.
>>> 0.000829620361328125
timeit.timeit('sum3(L)','from __main__ import sum1,sum2,sum3,sum4,this_implementation,L', number=100)/100.
>>> 0.4606760001182556
timeit.timeit('sum4(L)','from __main__ import sum1,sum2,sum3,sum4,this_implementation,L', number=100)/100.
>>> 0.18932826995849608
timeit.timeit('this_implementation(L)','from __main__ import sum1,sum2,sum3,sum4,this_implementation,L', number=100)/100.
>>> 0.002348129749298096
PEP 572 (Python 3.8에 예상 됨)의 할당 표현식 은 이를 해결하는 또 다른 방법을 제공합니다.
time_interval = [4, 6, 12]
total_time = 0
cum_time = [total_time := total_time + t for t in time_interval]
이것을 시도하십시오 : 누적 기능과 함께 연산자 추가는 실행 추가를 수행합니다.
import itertools
import operator
result = itertools.accumulate([1,2,3,4,5], operator.add)
list(result)
이 시도:
result = []
acc = 0
for i in time_interval:
acc += i
result.append(acc)
간단한 for
루프를 사용하여 선형 시간의 누적 합계 목록을 계산할 수 있습니다 .
def csum(lst):
s = lst.copy()
for i in range(1, len(s)):
s[i] += s[i-1]
return s
time_interval = [4, 6, 12]
print(csum(time_interval)) # [4, 10, 22]
표준 라이브러리 itertools.accumulate
는 더 빠른 대안이 될 수 있습니다 (C로 구현 되었기 때문에).
from itertools import accumulate
time_interval = [4, 6, 12]
print(list(accumulate(time_interval))) # [4, 10, 22]
In [42]: a = [4, 6, 12]
In [43]: [sum(a[:i+1]) for i in xrange(len(a))]
Out[43]: [4, 10, 22]
이다 slighlty 빠르게 발생 방법보다 상기 @Ashwini 의해 작은 목록을위한
In [48]: %timeit list(accumu([4,6,12]))
100000 loops, best of 3: 2.63 us per loop
In [49]: %timeit [sum(a[:i+1]) for i in xrange(len(a))]
100000 loops, best of 3: 2.46 us per loop
더 큰 목록의 경우 생성기가 확실하게 이동하는 방법입니다. . .
In [50]: a = range(1000)
In [51]: %timeit [sum(a[:i+1]) for i in xrange(len(a))]
100 loops, best of 3: 6.04 ms per loop
In [52]: %timeit list(accumu(a))
10000 loops, best of 3: 162 us per loop
다소 엉망이지만 작동하는 것 같습니다.
def cumulative_sum(l):
y = [0]
def inc(n):
y[0] += n
return y[0]
return [inc(x) for x in l]
I did think that the inner function would be able to modify the y
declared in the outer lexical scope, but that didn't work, so we play some nasty hacks with structure modification instead. It is probably more elegant to use a generator.
Without having to use Numpy, you can loop directly over the array and accumulate the sum along the way. For example:
a=range(10)
i=1
while((i>0) & (i<10)):
a[i]=a[i-1]+a[i]
i=i+1
print a
Results in:
[0, 1, 3, 6, 10, 15, 21, 28, 36, 45]
def cummul_sum(list_arguement):
cumm_sum_lst = []
cumm_val = 0
for eachitem in list_arguement:
cumm_val += eachitem
cumm_sum_lst.append(cumm_val)
return cumm_sum_lst
A pure python oneliner for cumulative sum:
cumsum = lambda X: X[:1] + cumsum([X[0]+X[1]] + X[2:]) if X[1:] else X
This is a recursive version inspired by recursive cumulative sums. Some explanations:
- The first term
X[:1]
is a list containing the previous element and is almost the same as[X[0]]
(which would complain for empty lists). - The recursive
cumsum
call in the second term processes the current element[1]
and remaining list whose length will be reduced by one. if X[1:]
is shorter forif len(X)>1
.
Test:
cumsum([4,6,12])
#[4, 10, 22]
cumsum([])
#[]
And simular for cumulative product:
cumprod = lambda X: X[:1] + cumprod([X[0]*X[1]] + X[2:]) if X[1:] else X
Test:
cumprod([4,6,12])
#[4, 24, 288]
l = [1,-1,3]
cum_list = l
def sum_list(input_list):
index = 1
for i in input_list[1:]:
cum_list[index] = i + input_list[index-1]
index = index + 1
return cum_list
print(sum_list(l))
In Python3, To find the cumulative sum of a list where the i
th element is the sum of the first i+1 elements from the original list, you may do:
a = [4 , 6 , 12]
b = []
for i in range(0,len(a)):
b.append(sum(a[:i+1]))
print(b)
OR you may use list comprehension:
b = [sum(a[:x+1]) for x in range(0,len(a))]
Output
[4,10,22]
lst = [4,6,12]
[sum(lst[:i+1]) for i in xrange(len(lst))]
If you are looking for a more efficient solution (bigger lists?) a generator could be a good call (or just use numpy
if you really care about perf).
def gen(lst):
acu = 0
for num in lst:
yield num + acu
acu += num
print list(gen([4, 6, 12]))
This would be Haskell-style:
def wrand(vtlg):
def helpf(lalt,lneu):
if not lalt==[]:
return helpf(lalt[1::],[lalt[0]+lneu[0]]+lneu)
else:
lneu.reverse()
return lneu[1:]
return helpf(vtlg,[0])
참고URL : https://stackoverflow.com/questions/15889131/how-to-find-the-cumulative-sum-of-numbers-in-a-list
'Program Tip' 카테고리의 다른 글
Highcharts 세로 막 대형 차트 내에서 각 범주의 색상을 어떻게 변경합니까? (0) | 2020.11.09 |
---|---|
PagerAdapter 시작 위치 (0) | 2020.11.09 |
Swift- 푸시 알림 배지 번호를 제거 하시겠습니까? (0) | 2020.11.09 |
RequireJS : 단일 "클래스"를 포함하는 모듈을 정의하는 방법은 무엇입니까? (0) | 2020.11.09 |
c # 새 양식을 연 다음 현재 양식을 닫으시겠습니까? (0) | 2020.11.09 |