Quale sarebbe un modo elegante e pitonico per implementare l'cumsum?
alternativa - se there'a già un modo integrato di farlo, che sarebbe ancora meglio, naturalmente ...Elegante cece piratesca
risposta
E 'disponibile in Numpy:
>>> import numpy as np
>>> np.cumsum([1,2,3,4,5])
array([ 1, 3, 6, 10, 15])
Oppure utilizzare itertools.accumulate
dal Python 3.2 :
>>> from itertools import accumulate
>>> list(accumulate([1,2,3,4,5]))
[ 1, 3, 6, 10, 15]
Se Numpy non è un'opzione, un anello generatore sarebbe la soluzione più elegante che posso pensare:
def cumsum(it):
total = 0
for x in it:
total += x
yield total
Es.
>>> list(cumsum([1,2,3,4,5]))
>>> [1, 3, 6, 10, 15]
bello e semplice con la resa totale :) –
per i loop sono pythonic
def cumsum(vec):
r = [vec[0]]
for val in vec[1:]:
r.append(r[-1] + val)
return r
@larsmans: cosa sarebbe 'r [-1]' essere in quel caso? – WolframH
a=[1,2,3,4,5]
def cumsum(a):
a=iter(a)
cc=[next(a)]
for i in a:
cc.append(cc[-1]+i)
return cc
print cumsum(a)
"[1, 3, 6, 10, 15]"
sul posto:
a=[1,2,3,4,5]
def cumsum(a):
for i in range(1,len(a)):
a[i]+=a[i-1]
cumsum(a)
print a
"[1, 3, 6, 10, 15]"
a=[1,2,3,4,5]
def cumsum(a):
b=a[:]
for i in range(1,len(a)):
b[i]+=b[i-1]
return b
print cumsum(a)
"[1, 3, 6, 10, 15]"
a = [1, 2, 3 ,4, 5]
# Using list comprehention
cumsum = [sum(a[:i+1]) for i in range(len(a))] # [1, 3, 6, 10, 15]
# Using map()
cumsum = map(lambda i: sum(a[:i+1]), range(len(a))) # [1, 3, 6, 10, 15]
Mentre questo è bello e facile, sappi che su una lista grande questo sarà molto lento! :) –
La mia idea era quella di utilizzare ridurre in maniera funzionale:
from operator import iadd
reduce(lambda acc, itm: iadd(acc, [acc[-1] + itm]), [1, 2, 3, 4, 5], [0])[1:]
>>> [1, 3, 6, 10, 15]
iadd dal modulo operatore ha la proprietà unica di eseguire un'aggiunta sul posto e restituire la destinazione come risultato.
Se questo [1:] copia fa rabbrividire, si potrebbe allo stesso modo fare:
from operator import iadd
reduce(lambda acc, itm: (iadd(acc[0], [acc[1] + itm]), acc[1] + itm),
[1, 2, 3, 4, 5], ([], 0))[0]
>>> [1, 3, 6, 10, 15]
ma ho scoperto che a livello locale il primo esempio è molto più veloce e generatori IMO sono più divinatorio di programmazione funzionale come 'ridurre ':
reduce(lambda acc, itm: (iadd(acc[0], [acc[1] + itm]), acc[1] + itm), values_ten, ([], 0))[0]
Average: 6.4593828736e-06
reduce(lambda acc, itm: (iadd(acc[0], [acc[1] + itm]), acc[1] + itm), values_mil, ([], 0))[0]
Average: 0.727404361961
reduce(lambda acc, itm: iadd(acc, [acc[-1] + itm]), values_ten, [0])[1:]
Average: 5.16271911336e-06
reduce(lambda acc, itm: iadd(acc, [acc[-1] + itm]), values_mil, [0])[1:]
Average: 0.524223491301
cumsum_rking(values_ten)
Average: 1.9828751369e-06
cumsum_rking(values_mil)
Average: 0.234241141632
list(cumsum_larsmans(values_ten))
Average: 2.02786211569e-06
list(cumsum_larsmans(values_mil))
Average: 0.201473119335
Ecco lo script benchmark, YMMV:
from timeit import timeit
def bmark(prog, setup, number):
duration = timeit(prog, setup=setup, number=number)
print prog
print 'Average:', duration/number
values_ten = list(xrange(10))
values_mil = list(xrange(1000000))
from operator import iadd
bmark('reduce(lambda acc, itm: (iadd(acc[0], [acc[1] + itm]), acc[1] + itm), \
values_ten, ([], 0))[0]',
setup='from __main__ import iadd, values_ten', number=1000000)
bmark('reduce(lambda acc, itm: (iadd(acc[0], [acc[1] + itm]), acc[1] + itm), \
values_mil, ([], 0))[0]',
setup='from __main__ import iadd, values_mil', number=10)
bmark('reduce(lambda acc, itm: iadd(acc, [acc[-1] + itm]), \
values_ten, [0])[1:]',
setup='from __main__ import iadd, values_ten', number=1000000)
bmark('reduce(lambda acc, itm: iadd(acc, [acc[-1] + itm]), \
values_mil, [0])[1:]',
setup='from __main__ import iadd, values_mil', number=10)
def cumsum_rking(iterable):
values = list(iterable)
for pos in xrange(1, len(values)):
values[pos] += values[pos - 1]
return values
bmark('cumsum_rking(values_ten)',
setup='from __main__ import cumsum_rking, values_ten', number=1000000)
bmark('cumsum_rking(values_mil)',
setup='from __main__ import cumsum_rking, values_mil', number=10)
def cumsum_larsmans(iterable):
total = 0
for value in iterable:
total += value
yield total
bmark('list(cumsum_larsmans(values_ten))',
setup='from __main__ import cumsum_larsmans, values_ten', number=1000000)
bmark('list(cumsum_larsmans(values_mil))',
setup='from __main__ import cumsum_larsmans, values_mil', number=10)
Ed ecco la mia versione di Python stringa:
Python 2.7 (r27:82525, Jul 4 2010, 09:01:59) [MSC v.1500 32 bit (Intel)] on win32
+1 per l'accurato benchmarking – Jonathan
def cumsum(a):
return map(lambda x: sum(a[0:x+1]), range(0, len(a)))
cumsum([1,2,3])
> [1, 3, 6]
- 1. Elegante modello AST
- 2. Modo elegante analizzando l'URL
- 3. Erlang: elegante tuple_to_list/1
- 4. Corrispondenza modello elegante Regex
- 5. elegante sottodista trovare nella lista
- 6. Elegante sovraccarico dell'operatore in D
- 7. Elegante JSON appiattire in Spark
- 8. Rails - qualche modo elegante per gestire 404s?
- 9. La soluzione più elegante isNumeric() per java
- 10. Elegante implementazione dell'elenco circolare unico in C?
- 11. Un modo più elegante per visualizzare null?
- 12. Definisci elegante array multidimensionale in C++ moderno
- 13. Modo elegante per testare la disponibilità SSH
- 14. PowerShell: un modo elegante per creare chiusure
- 15. Configurazione elegante della registrazione Python in Django
- 16. Suggerimenti per scrivere conciso ed elegante Java
- 17. Esiste una soluzione LINQ elegante per SomeButNotAll()?
- 18. Timing in modo elegante in C++
- 19. Modo elegante per eseguire aritmetica di tuple
- 20. Esiste un modo elegante per ripetere un'azione?
- 21. elegante delle versioni API in Rails
- 22. Esiste un modo più elegante/elegante per formattare il seguente numero di previdenza sociale come String con o senza Groovy?
- 23. cerca di un elegante ed efficiente biblioteca matrice C++
- 24. modo più elegante per cambiare 0 a 1 e viceversa
- 25. modo più elegante per implementare Pipe and Pattern filtro
- 26. Hamcrest - Un modo elegante per testare oggetti complessi con samepropertyvaluesas
- 27. Ricerca di un dicking elegante di Python Iterazione
- 28. dplyr: colSums su frame di dati sottogruppo (group_by): elegante
- 29. Elegante caso di haskell/gestione degli errori nelle monadi sequenziali
- 30. Formato elegante per un indirizzo MAC in Python 3.2
cumSum come in http://docs.scipy.org/doc/numpy/reference/generated/numpy.cumsum.html? –
http://docs.python.org/dev/library/itertools.html#itertools.accumulate – ChessMaster