목록의 누적 합계는 어떻게 찾나요?
time_interval = [4, 6, 12]
요.[4, 4+6, 4+6+12]
를 t = [4, 10, 22]
.
다음을 시도했습니다.
t1 = time_interval[0]
t2 = time_interval[1] + t1
t3 = time_interval[2] + t2
print(t1, t2, t3) # -> 4 10 22
다음과 같은 배열로 많은 수치 작업을 수행하는 경우 누적 합계 함수를 사용하는 것이 좋습니다.
import numpy as np
a = [4,6,12]
np.cumsum(a)
#array([4, 10, 22])
Numpy는 이런 종류의 경우 보통 순수한 비단뱀보다 빠릅니다.@Ashwini와 비교해서:
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+에서는 다음을 사용할 수 있습니다.
In [1]: lis = [4,6,12]
In [2]: from itertools import accumulate
In [3]: list(accumulate(lis))
Out[3]: [4, 10, 22]
3했는데 Python 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
는 약 고속입니다.
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
기능을 시험해 보세요.
import itertools
list(itertools.accumulate([1,2,3,4,5]))
# [1, 3, 6, 10, 15]
보기:
a = [4, 6, 12]
reduce(lambda c, x: c + [c[-1] + x], a, [0])[1:]
출력 예정(예상대로):
[4, 10, 22]
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]
.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]
표준 라이브러리가 더 빠른 대안일 수 있습니다(C에서 구현되었기 때문에).
from itertools import accumulate
time_interval = [4, 6, 12]
print(list(accumulate(time_interval))) # [4, 10, 22]
python 3.8부터 Assignment 식을 사용할 수 있게 되었기 때문에, 이러한 것을 실장하기 쉬워졌습니다.
nums = list(range(1, 10))
print(f'array: {nums}')
v = 0
cumsum = [v := v + n for n in nums]
print(f'cumsum: {cumsum}')
생산하다
array: [1, 2, 3, 4, 5, 6, 7, 8, 9]
cumsum: [1, 3, 6, 10, 15, 21, 28, 36, 45]
cum 곱, 평균 등을 구하는데도 동일한 기법을 적용할 수 있다.
p = 1
cumprod = [p := p * n for n in nums]
print(f'cumprod: {cumprod}')
s = 0
c = 0
cumavg = [(s := s + n) / (c := c + 1) for n in nums]
print(f'cumavg: {cumavg}')
을 낳다
cumprod: [1, 2, 6, 24, 120, 720, 5040, 40320, 362880]
cumavg: [1.0, 1.5, 2.0, 2.5, 3.0, 3.5, 4.0, 4.5, 5.0]
첫 번째 실행 중인 서브시퀀스 목록을 확인합니다.
subseqs = (seq[:i] for i in range(1, len(seq)+1))
요.sum
: " " " " :
sums = [sum(subseq) for subseq in subseqs]
(모든 프레픽스를 반복해서 추가하기 때문에 이 방법은 가장 효율적이지 않습니다.그러나 대부분의 사용 사례에서는 문제가 되지 않을 것이며, 실행 총계를 고려할 필요가 없다면 더 쉽게 이해할 수 있습니다.)
Python 3.2 이후를 사용하고 있는 경우는, 을 사용해 주세요.
sums = itertools.accumulate(seq)
3.1 버전을 있는 「할 수 (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, sys
L=list(range(10000))
if sys.version_info >= (3, 0):
reduce = functools.reduce
xrange = range
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
리스트의 길이와 퍼포먼스에 따라서는, 많은 답이 있을 수 있습니다.퍼포먼스를 생각하지 않고 생각할 수 있는 매우 간단한 방법은 다음과 같습니다.
a = [1, 2, 3, 4]
a = [sum(a[0:x]) for x in range(1, len(a)+1)]
print(a)
[1, 3, 6, 10]
이것은 리스트의 이해를 사용하는 것으로, 이것은 꽤 잘 동작할 수 있습니다.여기에서는 서브어레이에 여러 번 추가하고 있기 때문에, 이것을 즉석에서 간단하게 할 수 있습니다.
수고하셨습니다!
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]
이것을 시험해 보세요.
result = []
acc = 0
for i in time_interval:
acc += i
result.append(acc)
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))
Python3의 i
첫 ii+1 요소의 입니다.을 사용하다
a = [4 , 6 , 12]
b = []
for i in range(0,len(a)):
b.append(sum(a[:i+1]))
print(b)
또는 목록 이해를 사용할 수 있습니다.
b = [sum(a[:x+1]) for x in range(0,len(a))]
산출량
[4,10,22]
lst = [4, 6, 12]
[sum(lst[:i+1]) for i in xrange(len(lst))]
인 솔루션 큰 리스트 그냥 )이 될 수 .numpy
퍼포먼스를 정말 중시한다면)
def gen(lst):
acu = 0
for num in lst:
yield num + acu
acu += num
print list(gen([4, 6, 12]))
In [42]: a = [4, 6, 12]
In [43]: [sum(a[:i+1]) for i in xrange(len(a))]
Out[43]: [4, 10, 22]
이것은 작은 리스트의 경우 @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]
할 것 .y
외부 어휘 범위에서는 선언했지만, 효과가 없었기 때문에 대신 구조를 수정한 지저분한 해커들을 연기했습니다.발전기를 사용하는 것이 더 우아할 것이다.
Numpy를 사용할 필요 없이 어레이를 직접 루프하여 합계를 축적할 수 있습니다.예를 들어 다음과 같습니다.
a=range(10)
i=1
while((i>0) & (i<10)):
a[i]=a[i-1]+a[i]
i=i+1
print a
결과:
[0, 1, 3, 6, 10, 15, 21, 28, 36, 45]
누적 합계에 대한 순수 파이썬 오닐라이너:
cumsum = lambda X: X[:1] + cumsum([X[0]+X[1]] + X[2:]) if X[1:] else X
이것은 재귀 누적 합계에서 영감을 얻은 재귀 버전입니다.설명:
- 번째 용어 '1'
X[:1]
으로, "이러한 요소" 또는 "이러한 요소"와 거의 합니다.[X[0]]
(미국의) - ""
cumsum
를 처리합니다.[1]
길이가 1개 줄어드는 나머지 목록입니다. if X[1:]
보다 짧다if len(X)>1
.
테스트:
cumsum([4,6,12])
#[4, 10, 22]
cumsum([])
#[]
누적 제품에 대한 시뮬레이션:
cumprod = lambda X: X[:1] + cumprod([X[0]*X[1]] + X[2:]) if X[1:] else X
테스트:
cumprod([4,6,12])
#[4, 24, 288]
여기 또 다른 재미있는 해결책이 있습니다.이는 이해의 지시, 즉 목록 이해 범위 내에서 생성된 로컬 변수를 활용한다.
>>> [locals().setdefault(i, (elem + locals().get(i-1, 0))) for i, elem
in enumerate(time_interval)]
[4, 10, 22]
이게 뭐냐면locals()
는 각 반복을 검색합니다.
>>> [[locals().setdefault(i, (elem + locals().get(i-1, 0))), locals().copy()][1]
for i, elem in enumerate(time_interval)]
[{'.0': <enumerate at 0x21f21f7fc80>, 'i': 0, 'elem': 4, 0: 4},
{'.0': <enumerate at 0x21f21f7fc80>, 'i': 1, 'elem': 6, 0: 4, 1: 10},
{'.0': <enumerate at 0x21f21f7fc80>, 'i': 2, 'elem': 12, 0: 4, 1: 10, 2: 22}]
소규모 리스트에서도 퍼포먼스는 나쁘지 않습니다.
>>> %timeit list(accumulate([4, 6, 12]))
387 ns ± 7.53 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)
>>> %timeit np.cumsum([4, 6, 12])
5.31 µs ± 67.8 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
>>> %timeit [locals().setdefault(i, (e + locals().get(i-1,0))) for i,e in enumerate(time_interval)]
1.57 µs ± 12 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)
그리고 분명히 더 큰 리스트에는 실패한다.
>>> l = list(range(1_000_000))
>>> %timeit list(accumulate(l))
95.1 ms ± 5.22 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)
>>> %timeit np.cumsum(l)
79.3 ms ± 1.07 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)
>>> %timeit np.cumsum(l).tolist()
120 ms ± 1.23 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)
>>> %timeit [locals().setdefault(i, (e + locals().get(i-1, 0))) for i, e in enumerate(l)]
660 ms ± 5.14 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
그 방법은 형편없고 실용적이지 않지만, 확실히 재미있다.
아래 코드가 가장 쉬운 것 같습니다.
a=[1,1,2,1,2]
b=[a[0]]+[sum(a[0:i]) for i in range(2,len(a)+1)]
def cumulative_sum(list):
l = []
for i in range(len(list)):
new_l = sum(list[:i+1])
l.append(new_l)
return l
time_interval = [4, 6, 12]
print(cumulative_sum(time_interval)
좀 더 초보자 친화적인 해결책일 수도 있어요.
그래서 당신은 누적 합계 리스트를 작성해야 합니다.이를 수행하려면 for loop 및 .append() 메서드를 사용합니다.
time_interval = [4, 6, 12]
cumulative_sum = []
new_sum = 0
for i in time_interval:
new_sum += i
cumulative_sum.append(new_sum)
print(cumulative_sum)
또는 를 사용하여numpy
모듈
import numpy
time_interval = [4, 6, 12]
c_sum = numpy.cumsum(time_interval)
print(c_sum.tolist())
이것은 Haskell 스타일입니다.
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
'programing' 카테고리의 다른 글
Swift에서 사전에 요소를 추가하는 방법은 무엇입니까? (0) | 2023.04.22 |
---|---|
키가 첫 번째 열에 없는 Excel VLOOKUP (0) | 2023.04.17 |
XAML에서 변수를 정의하려면 어떻게 해야 하나요? (0) | 2023.04.17 |
오브젝트 내의 속성별로 목록을 정렬하는 방법 (0) | 2023.04.17 |
디렉토리의 파일을 루프 오버하고 경로를 변경하고 파일 이름에 접미사를 추가하는 방법 (0) | 2023.04.17 |