如何将数据从numpy数组复制到另一个数组

Cha*_*net 77 python numpy

将数据从数组b复制到数组a的最快方法是什么,而不修改数组a的地址.我需要这个,因为外部库(PyFFTW)使用指向我的数组的指针,该指针无法更改.

例如:

a = numpy.empty(n, dtype=complex)
for i in xrange(a.size):
  a[i] = b[i]
Run Code Online (Sandbox Code Playgroud)

有没有循环可以做到这一点?

Bri*_*ins 81

我相信

a = numpy.empty_like (b)
a[:] = b
Run Code Online (Sandbox Code Playgroud)

将快速复制.正如Funsi所提到的,最近版本的numpy也有这个copyto功能.

  • @ mg007我运行了一些测试,显示`empty()`比`zeros()`快10%左右.令人惊讶的是`empty_like()`更快.`copyto(a,b)`比数组语法`a [:] = b`快.请参阅https://gist.github.com/bhawkins/5095558 (12认同)
  • @ M.ElSaka`a = b`只是创建了对`b`的新引用.`a [:] = b`的意思是"设置`a`的所有元素都等于'b`的那些元素.差异很重要,因为numpy数组是可变类型. (9认同)
  • +1.但是[numpy.empty](http://docs.scipy.org/doc/numpy/reference/generated/numpy.empty.html)不会比[numpy.zeros]快得多(http:// docs. scipy.org/doc/numpy/reference/generated/numpy.zeros.html)? (4认同)
  • @MarcoSulla `b=a.copy()` 创建一个新数组。我们需要修改现有对象,而不是创建新对象。(OP 需要一个恒定的内存地址。) (3认同)
  • @Brian Hawkins 是对的。有关何时使用 `np.copyto(a, b)` 以及何时使用 `a = b.astype(b.dtype)` 来提高速度,请参阅以下答案:http://stackoverflow.com/a/33672015/ 3703716 (2认同)

小智 24

numpy版本1.7具有numpy.copyto函数,可以执行您要查找的内容:

numpy.copyto(dst,src)

将值从一个数组复制到另一个数组,>根据需要进行广播.

请参阅:http: //docs.scipy.org/doc/numpy-dev/reference/generated/numpy.copyto.html


小智 16

a = numpy.array(b)
Run Code Online (Sandbox Code Playgroud)

甚至比numpy v1.6的建议解决方案更快,并且也制作了数组的副本.然而,我可以不对copyto(a,b)测试它,因为我没有最新版本的numpy.


mab*_*mab 11

为了回答你的问题,我玩了一些变种并对它们进行了描述.

结论:将数据从numpy数组复制到另一个使用内置numpy函数之一numpy.array(src)numpy.copyto(dst, src)尽可能使用.

(但是如果dst已经分配了内存,则总是选择更晚的内存.重新使用内存.请参阅帖子末尾的分析.)

分析设置

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()
Run Code Online (Sandbox Code Playgroud)

分析代码

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)})
Run Code Online (Sandbox Code Playgroud)

结果为Windows 7英特尔i7处理器,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
Run Code Online (Sandbox Code Playgroud)


此外,请参阅分析变量的结果,其中目标的内存在值复制期间已预先分配,因为它y = np.empty_like(x)是设置的一部分:

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')
Run Code Online (Sandbox Code Playgroud)


ahe*_*elm 9

你可以轻松使用:

b = 1*a
Run Code Online (Sandbox Code Playgroud)

这是最快的方法,但也有一些问题.如果你不直接定义dtypea,也不会检查dtypeb,你可以惹上麻烦.例如:

a = np.arange(10)        # dtype = int64
b = 1*a                  # dtype = int64

a = np.arange(10.)       # dtype = float64
b = 1*a                  # dtype = float64

a = np.arange(10)        # dtype = int64
b = 1. * a               # dtype = float64
Run Code Online (Sandbox Code Playgroud)

我希望,我能说清楚.有时,只需一个小操作就可以更改数据类型.

  • 假设你有一个= numpy.empty(1000).现在,您需要填充数据,而不更改其在内存中的地址.如果执行[0] = 1,则不会重新创建数组,只需更改数组的内容即可. (2认同)

Pet*_*sen 7

你可以做很多不同的事情:

a=np.copy(b)
a=np.array(b) # Does exactly the same as np.copy
a[:]=b # a needs to be preallocated
a=b[np.arange(b.shape[0])]
a=copy.deepcopy(b)
Run Code Online (Sandbox Code Playgroud)

行不通的事情

a=b
a=b[:] # This have given my code bugs 
Run Code Online (Sandbox Code Playgroud)