Есть ли какая-либо стандартная библиотека/numpy, эквивалентная следующей функции:
def augmented_assignment_sum(iterable, start=0):
for n in iterable:
start += n
return start
?
Хотя sum(ITERABLE)
очень элегантен, он использует оператор +
вместо +=
, что в случае объектов np.ndarray
может повлиять на производительность.
Я проверил, что моя функция может быть такой же быстрой, как sum()
(в то время как ее эквивалент с использованием +
намного медленнее). Поскольку это чистая функция Python, я предполагаю, что ее производительность все еще ограничена, поэтому я ищу какую-то альтернативу:
In [49]: ARRAYS = [np.random.random((1000000)) for _ in range(100)]
In [50]: def not_augmented_assignment_sum(iterable, start=0):
...: for n in iterable:
...: start = start + n
...: return start
...:
In [51]: %timeit not_augmented_assignment_sum(ARRAYS)
63.6 ms ± 8.88 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)
In [52]: %timeit sum(ARRAYS)
31.2 ms ± 2.18 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)
In [53]: %timeit augmented_assignment_sum(ARRAYS)
31.2 ms ± 4.73 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)
In [54]: %timeit not_augmented_assignment_sum(ARRAYS)
62.5 ms ± 12.1 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)
In [55]: %timeit sum(ARRAYS)
37 ms ± 9.51 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)
In [56]: %timeit augmented_assignment_sum(ARRAYS)
27.7 ms ± 2.53 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)
Я пытался использовать functools.reduce
в сочетании с operator.iadd
, но его производительность аналогична:
In [79]: %timeit reduce(iadd, ARRAYS, 0)
33.4 ms ± 11.6 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)
In [80]: %timeit reduce(iadd, ARRAYS, 0)
29.4 ms ± 2.31 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)
Меня также интересует эффективность памяти, поэтому я предпочитаю расширенные задания, поскольку они не требуют создания промежуточных объектов.
374 ms ± 83.4 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
:-( Хотя это значительно быстрее, еслиARRAYS
является двумерным массивом. - person abukaj   schedule 14.11.2019axis=0
. Затем он принимает355 ms ± 16.4 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
:-( Внутри он используетnp.add.reduce()
(numpy v. 1.15.4) - person abukaj   schedule 15.11.2019np.dot(your_array, np.ones(len(your_array)))
. Должен перейти в BLAS и быть достаточно быстрым. - person user228395   schedule 19.11.2019np.dot
быстрее, чем представленные вами методы, но после того, как я установил MKL,np.sum
быстрее. - person user228395   schedule 19.11.2019not_augmented_assignment_sum
кажется постоянно быстрее и очень похож по производительности наsum
. На какой ты системе? (у меня ПК Linux, Python3.6.5, numpy 1.17.0) - person Paul Panzer   schedule 19.11.2019np.stack
обработки ваших массивов иnp.sum
обработки правильной оси? Или вы ХОТИТЕ скаляр? (В этом случае просто сложите и обычную сумму после) - person Gloweye   schedule 19.11.2019ARRAYS
(отредактировано). Моя система тестирования — Ubuntu 18.04 (2xIntel Xeon CPU E5-2609 v2 @ 2,50 ГГц, 64 ГБ ОЗУ), Python 3.6.7 Anaconda, numpy 1.15.4. - person abukaj   schedule 19.11.2019ARRAYS
— это последовательность множества разных массивов. Развеnp.dot(...)
не эквивалентноlen(your_array) * your_array
? - person abukaj   schedule 19.11.2019%timeit np.stack(ARRAYS).sum(axis=0)
это330 ms ± 23.5 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
. - person abukaj   schedule 19.11.2019+=
можно использовать эффективную схему роста. - person user2357112 supports Monica   schedule 19.11.2019cython
/numba
или собственное расширение c? - person Uri Goren   schedule 24.11.2019