Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/299.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/performance/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 如何加速numpy代码_Python_Performance_Numpy_Cython - Fatal编程技术网

Python 如何加速numpy代码

Python 如何加速numpy代码,python,performance,numpy,cython,Python,Performance,Numpy,Cython,我有以下代码。原则上它需要2^6*1000=64000次迭代,这是一个相当小的数字。然而,它需要在我的计算机上运行9秒,我想至少运行n=15 from __future__ import division import numpy as np import itertools n=6 iters = 1000 firstzero = 0 bothzero = 0 for S in itertools.product([-1,1], repeat = n+1): for i in xra

我有以下代码。原则上它需要2^6*1000=64000次迭代,这是一个相当小的数字。然而,它需要在我的计算机上运行9秒,我想至少运行n=15

from __future__ import division
import numpy as np
import itertools

n=6
iters = 1000
firstzero = 0
bothzero = 0
for S in itertools.product([-1,1], repeat = n+1):
    for i in xrange(iters):
        F = np.random.choice(np.array([-1,0,0,1], dtype=np.int8), size = n)
        while np.all(F ==0):
            F = np.random.choice(np.array([-1,0,0,1], dtype=np.int8), size = n)
        FS = np.convolve(F,S, 'valid')
        if (FS[0] == 0):
            firstzero += 1
        if np.all(FS==0):
            bothzero += 1

print "firstzero",    firstzero
print "bothzero",  bothzero
有没有可能把速度提高很多,或者我应该用C重写它

分析表明它将大部分时间花在

   258003    0.418    0.000    3.058    0.000 fromnumeric.py:1842(all)
   130003    1.245    0.000    2.907    0.000 {method 'choice' of 'mtrand.RandomState' objects}
   388006    2.488    0.000    2.488    0.000 {method 'reduce' of 'numpy.ufunc' objects}
   128000    0.731    0.000    2.215    0.000 numeric.py:873(convolve)
   258003    0.255    0.000    2.015    0.000 {method 'all' of 'numpy.ndarray' objects}
   258003    0.301    0.000    1.760    0.000 _methods.py:35(_all)
   130003    0.470    0.000    1.663    0.000 fromnumeric.py:2249(prod)
   644044    1.483    0.000    1.483    0.000 {numpy.core.multiarray.array}
   130003    0.164    0.000    1.193    0.000 _methods.py:27(_prod)
   258003    0.283    0.000    0.624    0.000 numeric.py:462(asanyarray)

通过一次生成所有随机选择,我很容易获得35-40%的加速:

for S in itertools.product([-1,1], repeat = n+1):
    Fx = np.random.choice(np.array([-1,0,0,1], dtype=np.int8), size=(iters,n))                                       
        for F in Fx:
这取代了xrange(iters)中i的
循环


为了超越这一点,我怀疑您可以使用scipy.signal.fftconvolve对卷积本身进行矢量化(np.convolve仅支持1D输入)。我没有尝试这个,部分是因为我写这篇文章时scipy.org是离线的,但我希望这能让你继续下去。主要思想是减少Python中的循环,尽可能用矢量化操作替换它们。

几乎完全矢量化的代码速度要快得多(16.9%),假设您的代码名为
f()

计时结果:

In [164]:

%timeit f()
firstzero 27171
bothzero 12151
firstzero 27206
bothzero 12024
firstzero 27272
bothzero 12135
firstzero 27173
bothzero 12079
1 loops, best of 3: 14.6 s per loop
In [165]:

%timeit g()
firstzero 27182
bothzero 11952
firstzero 27365
bothzero 12174
firstzero 27318
bothzero 12173
firstzero 27377
bothzero 12072
1 loops, best of 3: 2.47 s per loop

你能解释一下这段代码在做什么吗?@MrE它是计算两个随机数组的卷积的次数,一个比另一个长,具有特定的概率分布,第一个位置有0,或者两个位置都有0。只是一个注释。通过改进代码,您只能获得线性加速。除非你能获得99%的速度提升,否则你不会走得很远,除非你跳过O(2^n)复杂度
n=15
将始终以低于
2^15/2^6=2^9
的速度工作,因此要保持在同一时间内,您实际上需要将速度提高到系数512。@32是的。我怀疑,如果用C语言正确编码,比如用一个比我更好的编码员,目前的速度可能会快512倍。它并不是每次迭代都做很多事情。@user2179021我真的怀疑它=)。在我看来,通过改变语言/工具,你最多可以得到10个。请注意,您已经在使用专门的工具,程序不会在代码中花费时间。正如约翰所建议的,也许使用不同的工具才是最好的选择。但我认为你可能必须将其并行化,以获得更大的因素和更大的问题规模。。。你仍然会撞上O(2^n)墙,而不是迟早。但我祝你好运。也许n=15到20可以在合理的时间内计算。谢谢。我不太懂scipy.signal.fftconvolve。你是在建议做二维卷积吗?那几乎不行。你看,必须排除
np.all(F==0)
的行
Fx
必须以大于
(iters,n)
@user2179021卷积的大小生成,通过FFT进行的卷积可放大,以获得比常规卷积更好的更大阵列大小。详情请参见本页:太好了。非常感谢。不客气。我想先尝试矢量化,而不是
c
fortran
或其他。
numpy
scipy
中的很多东西都已经在引擎盖下了,因此,矢量化在至少一半的时间内都是必需的。
In [164]:

%timeit f()
firstzero 27171
bothzero 12151
firstzero 27206
bothzero 12024
firstzero 27272
bothzero 12135
firstzero 27173
bothzero 12079
1 loops, best of 3: 14.6 s per loop
In [165]:

%timeit g()
firstzero 27182
bothzero 11952
firstzero 27365
bothzero 12174
firstzero 27318
bothzero 12173
firstzero 27377
bothzero 12072
1 loops, best of 3: 2.47 s per loop