I am looking for fastest way to replace parts of pre-allocated numpy ndarray.
Below you can see sim_matrix (2D ndarray). "For loop" iterates over it rowwise and overwrites values given by levels (numpy.array).
There are fast ways, which are found:
numpy.copyto()numpy.fromiter()=assignment to slice
NOTE: For simplicity, I assign the same values on each iteration, it is not the case in production setup. In actual setup, levels contains different values for each row. Thus, using shortcut as numpy.repeat or numpy.hstack is discouraged as an answer.
Are there any faster ways to change parts of ndarray?
numpy_overwrite.py:
import numpy
panel_size = 365 * 7
rows = 1 * (1+1+2*4) * 10000
# rows = 100
levels = [1778.24] * panel_size
levels_array = numpy.fromiter(levels,dtype='single', count = len(levels))
sim_matrix = numpy.empty([rows, panel_size],dtype='single')
def _copyto(sim_matrix_, level_):
for i in range(sim_matrix_.shape[0]):
numpy.copyto(sim_matrix[i], level_)
def _fromiter(sim_matrix_, level_):
len_level = len(level_)
for i in range(sim_matrix_.shape[0]):
sim_matrix[i] = numpy.fromiter(level_,
dtype='single',
count = len_level)
def _just_assign(sim_matrix_, level_):
for i in range(sim_matrix_.shape[0]):
sim_matrix[i] = level_
numpy_overwrite_test.py
import timeit
import numpy_overwrite as npo
print('_fromiter')
print(timeit.timeit('npo._fromiter(npo.sim_matrix, npo.levels)', setup="import numpy_overwrite as npo;", number=3))
print(timeit.timeit('npo._fromiter(npo.sim_matrix, npo.levels_array)', setup="import numpy_overwrite as npo;", number=3))
print('_copyto')
print(timeit.timeit('npo._copyto(npo.sim_matrix, npo.levels)', setup="import numpy_overwrite as npo;", number=3))
print(timeit.timeit('npo._copyto(npo.sim_matrix, npo.levels_array)', setup="import numpy_overwrite as npo;", number=3))
print('_just_assign')
print(timeit.timeit('npo._just_assign(npo.sim_matrix, npo.levels)', setup="import numpy_overwrite as npo;", number=3))
print(timeit.timeit('npo._just_assign(npo.sim_matrix, npo.levels_array)', setup="import numpy_overwrite as npo;", number=3))
Run test
_fromiter
=========
from python list: 21.129429172957316
from numpy.array: 61.76275303697912
_copyto
=========
from python list: 52.4522930260282
from numpy.array: 0.7605530479922891
_just_assign
=========
from python list: 52.251478374004364
from numpy.array: 0.6351132979616523
passkeyword is useful herelevelswhich actually does have different values. Maybe randomly distributed?