Gibt es eine Standardbibliothek / ein numpy-Äquivalent der folgenden Funktion:
def augmented_assignment_sum(iterable, start=0):
for n in iterable:
start += n
return start
?
Obwohl sum(ITERABLE)
es sehr elegant ist, wird +
stattdessen der Operator verwendet +=
, was bei np.ndarray
Objekten die Leistung beeinträchtigen kann.
Ich habe getestet, dass meine Funktion möglicherweise so schnell ist wie sum()
(während die entsprechende Verwendung +
viel langsamer ist). Da es sich um eine reine Python-Funktion handelt, ist ihre Leistung vermutlich immer noch beeinträchtigt, daher suche ich nach einer Alternative:
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)
Ich habe versucht, in functools.reduce
Kombination mit zu verwenden operator.iadd
, aber die Leistung ist ähnlich:
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)
Ich interessiere mich auch für Speichereffizienz und bevorzuge daher erweiterte Zuweisungen, da keine Zwischenobjekte erstellt werden müssen.
374 ms ± 83.4 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
:-( Obwohl es erheblich schneller ist, wenn ARRAYS
2D-Array ist.
axis=0
. Dann dauert es 355 ms ± 16.4 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
:-( Intern verwendet es np.add.reduce()
(numpy v. 1.15.4)
np.dot(your_array, np.ones(len(your_array)))
. Sollte zu BLAS wechseln und relativ schnell sein.
np.add.reduce(ARRAYS)
?