Existe algum equivalente padrão de biblioteca / numpy da seguinte função:
def augmented_assignment_sum(iterable, start=0):
for n in iterable:
start += n
return start
?
Embora sum(ITERABLE)
seja muito elegante, ele usa +
operador em vez de +=
, o que, no caso de np.ndarray
objetos, pode afetar o desempenho.
Eu testei que minha função pode ser tão rápida quanto sum()
(enquanto seu uso equivalente +
é muito mais lento). Como é uma função Python pura, acho que seu desempenho ainda é deficiente, portanto, estou procurando alguma alternativa:
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)
Eu tentei usar functools.reduce
combinado com operator.iadd
, mas seu desempenho é semelhante:
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)
Também estou interessado em eficiência de memória, portanto, prefiro atribuições aumentadas, pois não exigem a criação de objetos intermediários.
374 ms ± 83.4 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
:-( Embora seja consideravelmente mais rápido se ARRAYS
for um array 2D. #
axis=0
. Em seguida, ele leva 355 ms ± 16.4 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
:-( Internamente ele usa np.add.reduce()
(v numpy 1.15.4.)
np.dot(your_array, np.ones(len(your_array)))
. Deve transferir para o BLAS e ser razoavelmente rápido.
np.add.reduce(ARRAYS)
?