Что было бы элегантным и путинским способом реализации cumsum?
В качестве альтернативы - если there'a уже встроенный способ сделать это, это было бы еще лучше, конечно ...Элегантный pythonic cumsum
ответ
Он доступен в Numpy:
>>> import numpy as np
>>> np.cumsum([1,2,3,4,5])
array([ 1, 3, 6, 10, 15])
Или использовать itertools.accumulate
поскольку Python 3.2 :
>>> from itertools import accumulate
>>> list(accumulate([1,2,3,4,5]))
[ 1, 3, 6, 10, 15]
Если Numpy не вариант, петля генератора будет наиболее элегантным решением я могу думать:
def cumsum(it):
total = 0
for x in it:
total += x
yield total
Исх.
>>> list(cumsum([1,2,3,4,5]))
>>> [1, 3, 6, 10, 15]
приятный и простой с итоговым итогом :) –
для петель являются вещий
def cumsum(vec):
r = [vec[0]]
for val in vec[1:]:
r.append(r[-1] + val)
return r
@larsmans: что бы 'r [-1]' быть в этом случае? – 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]"
на месте:
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]
Хотя это приятно и легко, будьте предупреждены, что в большом списке это будет очень медленно! :) –
Моя идея состояла в том, чтобы использовать сократить в функциональной форме:
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 из модуля оператора обладает уникальным свойством выполнять добавление на месте и возвращать цель в результате.
Если [1:] копия делает вас съеживаться, вы также могли бы сделать:
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]
Но я обнаружил, что локально первый пример гораздо быстрее и генераторы ИМО более вещий, чем функциональное программирование, как «уменьшить «:
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
Вот тест сценарий, 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)
А вот мой Python версии строка:
Python 2.7 (r27:82525, Jul 4 2010, 09:01:59) [MSC v.1500 32 bit (Intel)] on win32
+1 для тщательного бенчмаркинга – 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. Элегантный метод String (как быть более Pythonic)
- 2. Более элегантный/Pythonic способ печати элементов кортежа?
- 3. Самый элегантный/эффективный/Pythonic способ вычисления нескольких параллельных массивов?
- 4. Pythonic, элегантный способ динамического определения списка статически определенных функций?
- 5. Более элегантный/pythonic способ добавить к массиву или создать его
- 6. Есть ли более элегантный/pythonic способ выразить эту конструкцию?
- 7. Есть ли элегантный, Pythonic способ подсчета обработанных данных?
- 8. Элегантный и Pythonic подход к изменению списка объектов
- 9. Подробнее pythonic/элегантный способ сделать это нарезкой строки Python?
- 10. Элегантный и короткий (pythonic) способ найти самый низкий неиспользованный номер
- 11. cumsum по группе
- 12. Проблема с функцией cumsum
- 13. Условный cumsum с сбросом
- 14. cumsum using ddply
- 15. ggplot2 и cumsum()
- 16. cumsum начиная с NA
- 17. Cumsum и vectorized slicing
- 18. Python numpy nonzero cumsum
- 19. Использование cumsum колоннами
- 20. Cumsum сброс на NaN
- 21. cumsum только внутри групп?
- 22. R cumunique like cumsum
- 23. Условный мутант cumsum dlpyr
- 24. векторизовать cumsum в R
- 25. Эквивалент cumsum для строки в R
- 26. г cumsum-как функция для расщепления dataframe
- 27. Cumsum игнорирует NA с сбросом
- 28. cumsum() в течение нескольких колонок
- 29. Условная cumsum на основе столбца
- 30. Почему диаграмма.CumReturns diff to cumsum?
cumsum как в http://docs.scipy.org/doc/numpy/reference/generated/numpy.cumsum.html? –
http://docs.python.org/dev/library/itertools.html#itertools.accumulate – ChessMaster