Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/297.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 C扩展中的可变长度数组?_Python_C_Numpy_Variable Length Array - Fatal编程技术网

Python 返回Numpy C扩展中的可变长度数组?

Python 返回Numpy C扩展中的可变长度数组?,python,c,numpy,variable-length-array,Python,C,Numpy,Variable Length Array,我以前做过一些Numpy C扩展,这对我很有帮助,但据我所知,返回的参数都是固定长度的 有没有办法让Numpy C-extension返回一个可变长度的Numpy数组呢?您可能会发现,使用Numpy C-API在Cython中创建Numpy扩展更容易,因为它允许您混合python和C对象,从而简化了过程。在这种情况下,创建可变长度数组没有什么困难,只需指定具有任意形状的数组即可 这本书可能是关于这个话题的最好的资料来源 例如,我最近编写了一个函数: import numpy as np cimp

我以前做过一些Numpy C扩展,这对我很有帮助,但据我所知,返回的参数都是固定长度的


有没有办法让Numpy C-extension返回一个可变长度的Numpy数组呢?

您可能会发现,使用Numpy C-API在Cython中创建Numpy扩展更容易,因为它允许您混合python和C对象,从而简化了过程。在这种情况下,创建可变长度数组没有什么困难,只需指定具有任意形状的数组即可

这本书可能是关于这个话题的最好的资料来源

例如,我最近编写了一个函数:

import numpy as np
cimport numpy as np
cimport cython

dtype = np.double
ctypedef double dtype_t

np.import_ufunc()
np.import_array()

def ewma(a, d, axis):
    #Calculates the exponentially weighted moving average of array a along axis using the parameter d.
    cdef void *args[1]

    cdef double weight[1]
    weight[0] = <double>np.exp(-d)


    args[0] = &weight[0]

    return apply_along_axis(&ewma_func, np.array(a, dtype = float), np.double, np.double, False, &(args[0]), <int>axis)

cdef void ewma_func(int n, void* aData,int astride, void* oData, int ostride, void** args):
    #Exponentially weighted moving average calculation function 

    cdef double avg = 0.0
    cdef double weight = (<double*>(args[0]))[0]
    cdef int i = 0

    for i in range(n): 

        avg = (<double*>((<char*>aData) + i * astride))[0]*weight + avg * (1.0 - weight) 


        (<double*>((<char*>oData) + i * ostride))[0] = avg  

ctypedef void (*func_1d)(int, void*, int, void*, int, void **)

cdef apply_along_axis(func_1d function, a, adtype, odtype, reduce,  void** args, int axis):
    #generic function for applying a cython function along a particular dimension

    oshape = list(a.shape)

    if reduce :
        oshape[axis] = 1

    out = np.empty(oshape, odtype)

    cdef np.flatiter ita, ito

    ita = np.PyArray_IterAllButAxis(a,   &axis)
    ito = np.PyArray_IterAllButAxis(out, &axis)

    cdef int axis_length = a.shape[axis]
    cdef int a_axis_stride = a.strides[axis]
    cdef int o_axis_stride = out.strides[axis]

    if reduce: 
        o_axis_stride = 0

    while np.PyArray_ITER_NOTDONE(ita):

        function(axis_length, np.PyArray_ITER_DATA (ita), a_axis_stride, np.PyArray_ITER_DATA (ito), o_axis_stride, args)

        np.PyArray_ITER_NEXT(ita)
        np.PyArray_ITER_NEXT(ito)

    if reduce:  
        oshape.pop(axis)
        out.shape = oshape

    return out  
将numpy导入为np
cimport numpy作为np
西姆波特赛顿酒店
dtype=np.double
ctypedef双数据类型
np.import_ufunc()
np.import_数组()
def ewma(a、d、轴):
#使用参数d计算阵列a沿轴的指数加权移动平均值。
cdef void*args[1]
cdef双倍重量[1]
权重[0]=np.exp(-d)
参数[0]=&权重[0]
返回沿_轴应用_(&ewma_func,np.array(a,dtype=float),np.double,np.double,False,&(args[0]),轴)
cdef void ewma_func(int n,void*aData,int astride,void*oData,int ostride,void**args):
#指数加权移动平均计算函数
cdef双平均值=0.0
cdef双重权重=((args[0]))[0]
cdef int i=0
对于范围(n)中的i:
平均值=((aData)+i*跨骑))[0]*重量+平均值*(1.0-重量)
((oData)+i*鸵鸟))[0]=平均值
ctypedef void(*func_1d)(int,void*,int,void*,int,void**)
cdef沿_轴应用(func_1d函数、a、adtype、odtype、reduce、void**args、int轴):
#用于沿特定维度应用cython函数的泛型函数
oshape=列表(a.shape)
如果减少:
oshape[轴]=1
out=np.空(oshape,odtype)
cdef np.flatiter ita,ito
ita=np.PyArray\u IterAllButAxis(a和轴)
ito=np.PyArray\u IterAllButAxis(输出和轴)
cdef int axis_length=a.shape[轴]
cdef int a_轴_步长=a.步长[轴]
cdef int o_轴_跨步=向外。跨步[轴]
如果减少:
o_轴_步幅=0
而np.PyArray_ITER_NOTDONE(ita):
函数(轴长度、np.PyArray\u ITER\u数据(ita)、a\u轴步长、np.PyArray\u ITER\u数据(ito)、o\u轴步长、args)
np.PyArray\u ITER\u NEXT(ita)
np.PyArray\u ITER\u NEXT(ito)
如果减少:
oshape.pop(轴)
out.shape=oshape
返回

如果这不适合您,则有一个函数用于生成具有任意形状的新空数组()。

我将您的问题解释为“我有一个函数,它接受长度为n的NumPy数组,但它将返回另一个长度为m而非n的数组。”如果是这种情况,您需要在扩展中
malloc
一个新的C数组,例如

new_array=malloc(m*sizeof(int64));//或者不管你的数据类型是什么
然后用它创建一个新的NumPy数组。本例假设为1D阵列:

int npy_intp dims[1];
dims[0]=m;
PyArrayObject*out=(PyArrayObject*)PyArray_SimpleNewFromData(1,//1D数组
dims,//尺寸
NPY_INT64,//类型
新阵列);
PyArray_ENABLEFLAGS(out,NPY_ARRAY_OWNDATA);
然后返回新数组。这里的重要部分是设置
NPY\u ARRAY\u OWNDATA
标志,以便在对Python对象进行垃圾收集时释放您分配的内存。

什么是“可变长度numpy数组”?据我所知,numpy数组的大小一旦设置好就无法调整大小。