2011-01-07 2 views
2

나는 Numpy C-extensions을이 전에 site에서 큰 도움을 받아 만들었지 만 반환 된 매개 변수는 모두 고정 길이라는 것을 알 수 있습니다.Numpy C- 확장자의 가변 길이 배열을 반환 하시겠습니까?

Numpy C- 확장자 대신 가변 길이 numpy 배열을 반환하는 방법이 있습니까?

+2

"가변 길이 numpy 배열"이란 무엇입니까? 내가 아는 한, 크기가 설정된 배열의 크기를 조정할 수 없습니다. – albertov

답변

3

파이썬과 c 객체를 혼합 할 수있게 해주는 Numpy C-API를 사용하여 Cyphon에서 numpy 확장을 만드는 것이 더 쉽습니다. 이 경우 가변 길이 배열을 만드는 것이 거의 어렵지 않으므로 임의의 모양으로 배열을 간단히 지정할 수 있습니다.

Cython numpy tutorial이이 주제에 대한 최고의 출처 일 수 있습니다. 이 당신을 적합하지 않는 경우, 임의의 형상 (link), 새로운 빈 상태 (empty)의 배열을 만들기위한 기능이

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 

:

예를 들어, 여기에 내가 최근에 쓴 기능입니다.