Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/arrays/13.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 Cythonize两个小numpy函数,需要帮助吗 问题_Python_Arrays_Numpy_Cython_Memoryview - Fatal编程技术网

Python Cythonize两个小numpy函数,需要帮助吗 问题

Python Cythonize两个小numpy函数,需要帮助吗 问题,python,arrays,numpy,cython,memoryview,Python,Arrays,Numpy,Cython,Memoryview,为了科学的目的,我尝试将两个主要处理numpy ndarray的小函数进行Cythonization。这两个smalls函数在遗传算法中被调用了数百万次,占了算法所花费的大部分时间 我自己也取得了一些进步,两种方法都很好,但我的速度只提高了一点点(10%)。更重要的是,cython--annotate表明大部分代码仍在使用Python 代码 第一个功能: 此函数的目的是获取数据片段,在内部嵌套循环中调用它数百万次。根据数据[1][1]中的布尔值,我们可以按正向或反向顺序获取切片 #Ipython

为了科学的目的,我尝试将两个主要处理numpy ndarray的小函数进行Cythonization。这两个smalls函数在遗传算法中被调用了数百万次,占了算法所花费的大部分时间

我自己也取得了一些进步,两种方法都很好,但我的速度只提高了一点点(10%)。更重要的是,cython--annotate表明大部分代码仍在使用Python

代码 第一个功能: 此函数的目的是获取数据片段,在内部嵌套循环中调用它数百万次。根据数据[1][1]中的布尔值,我们可以按正向或反向顺序获取切片

#Ipython notebook magic for cython
%%cython --annotate
import numpy as np
from scipy import signal as scisignal

cimport cython
cimport numpy as np
def get_signal(data):
    #data[0] contains the data structure containing the numpy arrays
    #data[1][0] contains the position to slice
    #data[1][1] contains the orientation to slice, forward = 0, reverse = 1

    cdef int halfwinwidth = 100
    cdef int midpoint = data[1][0]
    cdef int strand = data[1][1]
    cdef int start = midpoint - halfwinwidth
    cdef int end = midpoint + halfwinwidth
    #the arrays we want to slice
    cdef np.ndarray r0 = data[0]['normals_forward']
    cdef np.ndarray r1 = data[0]['normals_reverse']
    cdef np.ndarray r2 = data[0]['normals_combined']
    if strand == 0:
        normals_forward = r0[start:end]
        normals_reverse = r1[start:end]
        normals_combined = r2[start:end]
    else:
        normals_forward = r1[end - 1:start - 1: -1]
        normals_reverse = r0[end - 1:start - 1: -1]
        normals_combined = r2[end - 1:start - 1: -1]
    #return the result as a tuple
    row = (normals_forward,
           normals_reverse,
           normals_combined)
    return row
第二功能 这一个得到一个numpy数组的元组列表,我们想将数组元素相加,然后对它们进行规范化,得到交集的积分

def calculate_signal(list signal):
    cdef int halfwinwidth = 100
    cdef np.ndarray profile_normals_forward = np.zeros(halfwinwidth * 2, dtype='f')
    cdef np.ndarray profile_normals_reverse = np.zeros(halfwinwidth * 2, dtype='f')
    cdef np.ndarray profile_normals_combined = np.zeros(halfwinwidth * 2, dtype='f')
    #b is a tuple of 3 np.ndarrays containing 200 floats
    #here we add them up elementwise
    for b in signal:
        profile_normals_forward += b[0]
        profile_normals_reverse += b[1]
        profile_normals_combined += b[2]
    #normalize the arrays
    cdef int count = len(signal)

    #print "Normalizing to number of elements"
    profile_normals_forward /= count
    profile_normals_reverse /= count
    profile_normals_combined /= count
    intersection_signal = scisignal.detrend(np.fmin(profile_normals_forward, profile_normals_reverse))
    intersection_signal[intersection_signal < 0] = 0
    intersection = np.sum(intersection_signal)

    results = {"intersection": intersection,
               "profile_normals_forward": profile_normals_forward,
               "profile_normals_reverse": profile_normals_reverse,
               "profile_normals_combined": profile_normals_combined,
               }
    return results
def计算_信号(列表信号):
cdef int halfwinwidth=100
cdef np.ndarray剖面图\u法线\u正向=np.0(半宽度*2,dtype='f')
cdef np.ndarray剖面图\u法线\u反转=np.0(半宽度*2,数据类型='f')
cdef np.ndarray配置文件\u法线\u组合=np.0(半宽*2,dtype='f')
#b是包含200个浮点数的3个np.ndarray的元组
#在这里,我们将它们按元素相加
对于b输入信号:
纵断面法线正向+=b[0]
纵断面法线反转+=b[1]
纵断面法线组合+=b[2]
#规范化数组
cdef int count=len(信号)
#打印“规格化到元素数”
纵断面\法线\正向/=计数
纵断面\法线\反转/=计数
纵断面\法线\组合/=计数
交叉口信号=scisignal.detrend(np.fmin(纵断面法线向前,纵断面法线向后))
交叉口信号[交叉口信号<0]=0
交叉口=np.和(交叉口信号)
结果={“交叉点”:交叉点,
“纵断面法线向前”:纵断面法线向前,
“纵断面法线反转”:纵断面法线反转,
“纵断面法线组合”:纵断面法线组合,
}
返回结果

非常感谢您的帮助-我尝试使用内存视图,但由于某些原因,代码变得越来越慢。

在修复数组cdef后(如前所述,使用指定的数据类型),您可能应该将例程放入cdef函数中(该函数只能由同一脚本中的def函数调用)

在函数声明中,您需要提供类型(如果是数组numpy,还需要提供维度):


不过,我不确定使用dict是不是一个好主意。您可以使用numpy的列或行切片,如数据[:,0]。

cdef np.ndarray
不会提供巨大的加速。您必须指定
dtype
,才能获得真正的提升。(这种语法已经被弃用了。)如果函数1被调用了数百万次,你应该使用
cdef
来调用这个函数,并将调用这个函数的例程也放在Cython中。。。另一个问题可能是
数据
是一本字典,我不确定这是否是获得真正改进的最佳方式。对于
数据
您可能应该使用
ndarray
,新语法是否为MemoryView类型?因为我尝试将cdef float[:]作为一个类型,但由于某些原因,性能下降了300%。请指定类型,并使用C类型代替Python类型。顺便说一句,numba可能也不错。这可能是一个很好的时间来指出。NUMBA是Python/NuMPy的JIT编译器,在我的测试中,自动编译功能与优化的Cython大致相同。
cdef get_signal(numpy.ndarray[DTYPE_t, ndim=3] data):