How to copy data from a numpy array to another
I believe
a = numpy.empty_like(b)
a[:] = b
will copy the values quickly. As Funsi mentions, recent versions of numpy also have the copyto
function.
NumPy version 1.7 has the numpy.copyto
function that does what you are looking for:
numpy.copyto(dst, src)
Copies values from one array to another, broadcasting as necessary.
See: https://docs.scipy.org/doc/numpy/reference/generated/numpy.copyto.html
a = numpy.array(b)
is even faster than the suggested solutions up to numpy v1.6 and makes a copy of the array as well. I could however not test it against copyto(a,b), since I don't have the most recent version of numpy.
To answer your question, I played with some variants and profiled them.
Conclusion: to copy data from a numpy array to another use one of the built-in numpy functions numpy.array(src)
or numpy.copyto(dst, src)
wherever possible.
(But always choose the later if dst
's memory is already allocated, to reuse the memory. See profiling at the end of the post.)
profiling setup
import timeit
import numpy as np
import pandas as pd
from IPython.display import display
def profile_this(methods, setup='', niter=10 ** 4, p_globals=None, **kwargs):
if p_globals is not None:
print('globals: {0}, tested {1:.0e} times'.format(p_globals, niter))
timings = np.array([timeit.timeit(method, setup=setup, number=niter,
globals=p_globals, **kwargs) for
method in methods])
ranking = np.argsort(timings)
timings = np.array(timings)[ranking]
methods = np.array(methods)[ranking]
speedups = np.amax(timings) / timings
pd.set_option('html', False)
data = {'time (s)': timings,
'speedup': ['{:.2f}x'.format(s) if 1 != s else '' for s in speedups],
'methods': methods}
data_frame = pd.DataFrame(data, columns=['time (s)', 'speedup', 'methods'])
display(data_frame)
print()
profiling code
setup = '''import numpy as np; x = np.random.random(n)'''
methods = (
'''y = np.zeros(n, dtype=x.dtype); y[:] = x''',
'''y = np.zeros_like(x); y[:] = x''',
'''y = np.empty(n, dtype=x.dtype); y[:] = x''',
'''y = np.empty_like(x); y[:] = x''',
'''y = np.copy(x)''',
'''y = x.astype(x.dtype)''',
'''y = 1*x''',
'''y = np.empty_like(x); np.copyto(y, x)''',
'''y = np.empty_like(x); np.copyto(y, x, casting='no')''',
'''y = np.empty(n)\nfor i in range(x.size):\n\ty[i] = x[i]'''
)
for n, it in ((2, 6), (3, 6), (3.8, 6), (4, 6), (5, 5), (6, 4.5)):
profile_this(methods[:-1:] if n > 2 else methods, setup,
niter=int(10 ** it), p_globals={'n': int(10 ** n)})
results for Windows 7 on Intel i7 CPU, CPython v3.5.0, numpy v1.10.1.
globals: {'n': 100}, tested 1e+06 times
time (s) speedup methods
0 0.386908 33.76x y = np.array(x)
1 0.496475 26.31x y = x.astype(x.dtype)
2 0.567027 23.03x y = np.empty_like(x); np.copyto(y, x)
3 0.666129 19.61x y = np.empty_like(x); y[:] = x
4 0.967086 13.51x y = 1*x
5 1.067240 12.24x y = np.empty_like(x); np.copyto(y, x, casting=...
6 1.235198 10.57x y = np.copy(x)
7 1.624535 8.04x y = np.zeros(n, dtype=x.dtype); y[:] = x
8 1.626120 8.03x y = np.empty(n, dtype=x.dtype); y[:] = x
9 3.569372 3.66x y = np.zeros_like(x); y[:] = x
10 13.061154 y = np.empty(n)\nfor i in range(x.size):\n\ty[...
globals: {'n': 1000}, tested 1e+06 times
time (s) speedup methods
0 0.666237 6.10x y = x.astype(x.dtype)
1 0.740594 5.49x y = np.empty_like(x); np.copyto(y, x)
2 0.755246 5.39x y = np.array(x)
3 1.043631 3.90x y = np.empty_like(x); y[:] = x
4 1.398793 2.91x y = 1*x
5 1.434299 2.84x y = np.empty_like(x); np.copyto(y, x, casting=...
6 1.544769 2.63x y = np.copy(x)
7 1.873119 2.17x y = np.empty(n, dtype=x.dtype); y[:] = x
8 2.355593 1.73x y = np.zeros(n, dtype=x.dtype); y[:] = x
9 4.067133 y = np.zeros_like(x); y[:] = x
globals: {'n': 6309}, tested 1e+06 times
time (s) speedup methods
0 2.338428 3.05x y = np.array(x)
1 2.466636 2.89x y = x.astype(x.dtype)
2 2.561535 2.78x y = np.empty_like(x); np.copyto(y, x)
3 2.603601 2.74x y = np.empty_like(x); y[:] = x
4 3.005610 2.37x y = np.empty_like(x); np.copyto(y, x, casting=...
5 3.215863 2.22x y = np.copy(x)
6 3.249763 2.19x y = 1*x
7 3.661599 1.95x y = np.empty(n, dtype=x.dtype); y[:] = x
8 6.344077 1.12x y = np.zeros(n, dtype=x.dtype); y[:] = x
9 7.133050 y = np.zeros_like(x); y[:] = x
globals: {'n': 10000}, tested 1e+06 times
time (s) speedup methods
0 3.421806 2.82x y = np.array(x)
1 3.569501 2.71x y = x.astype(x.dtype)
2 3.618747 2.67x y = np.empty_like(x); np.copyto(y, x)
3 3.708604 2.61x y = np.empty_like(x); y[:] = x
4 4.150505 2.33x y = np.empty_like(x); np.copyto(y, x, casting=...
5 4.402126 2.19x y = np.copy(x)
6 4.917966 1.96x y = np.empty(n, dtype=x.dtype); y[:] = x
7 4.941269 1.96x y = 1*x
8 8.925884 1.08x y = np.zeros(n, dtype=x.dtype); y[:] = x
9 9.661437 y = np.zeros_like(x); y[:] = x
globals: {'n': 100000}, tested 1e+05 times
time (s) speedup methods
0 3.858588 2.63x y = x.astype(x.dtype)
1 3.873989 2.62x y = np.array(x)
2 3.896584 2.60x y = np.empty_like(x); np.copyto(y, x)
3 3.919729 2.58x y = np.empty_like(x); np.copyto(y, x, casting=...
4 3.948563 2.57x y = np.empty_like(x); y[:] = x
5 4.000521 2.53x y = np.copy(x)
6 4.087255 2.48x y = np.empty(n, dtype=x.dtype); y[:] = x
7 4.803606 2.11x y = 1*x
8 6.723291 1.51x y = np.zeros_like(x); y[:] = x
9 10.131983 y = np.zeros(n, dtype=x.dtype); y[:] = x
globals: {'n': 1000000}, tested 3e+04 times
time (s) speedup methods
0 85.625484 1.24x y = np.empty_like(x); y[:] = x
1 85.693316 1.24x y = np.empty_like(x); np.copyto(y, x)
2 85.790064 1.24x y = np.empty_like(x); np.copyto(y, x, casting=...
3 86.342230 1.23x y = np.empty(n, dtype=x.dtype); y[:] = x
4 86.954862 1.22x y = np.zeros(n, dtype=x.dtype); y[:] = x
5 89.503368 1.18x y = np.array(x)
6 91.986177 1.15x y = 1*x
7 95.216021 1.11x y = np.copy(x)
8 100.524358 1.05x y = x.astype(x.dtype)
9 106.045746 y = np.zeros_like(x); y[:] = x
Also, see results for a variant of the profiling where the destination's memory is already pre-allocated during value copying, since y = np.empty_like(x)
is part of the setup:
globals: {'n': 100}, tested 1e+06 times
time (s) speedup methods
0 0.328492 2.33x np.copyto(y, x)
1 0.384043 1.99x y = np.array(x)
2 0.405529 1.89x y[:] = x
3 0.764625 np.copyto(y, x, casting='no')
globals: {'n': 1000}, tested 1e+06 times
time (s) speedup methods
0 0.453094 1.95x np.copyto(y, x)
1 0.537594 1.64x y[:] = x
2 0.770695 1.15x y = np.array(x)
3 0.884261 np.copyto(y, x, casting='no')
globals: {'n': 6309}, tested 1e+06 times
time (s) speedup methods
0 2.125426 1.20x np.copyto(y, x)
1 2.182111 1.17x y[:] = x
2 2.364018 1.08x y = np.array(x)
3 2.553323 np.copyto(y, x, casting='no')
globals: {'n': 10000}, tested 1e+06 times
time (s) speedup methods
0 3.196402 1.13x np.copyto(y, x)
1 3.523396 1.02x y[:] = x
2 3.531007 1.02x y = np.array(x)
3 3.597598 np.copyto(y, x, casting='no')
globals: {'n': 100000}, tested 1e+05 times
time (s) speedup methods
0 3.862123 1.01x np.copyto(y, x)
1 3.863693 1.01x y = np.array(x)
2 3.873194 1.01x y[:] = x
3 3.909018 np.copyto(y, x, casting='no')