2013-05-16 25 views
6

Yeni bir şey öğrenmek uğruna şu anda C'deki numpy.mean() işlevini yeniden düzenlemeye çalışıyorum. Bu, bir 3B dizi almalı ve bir 2D dizisini eksen 0 boyunca elemanlar. Tüm değerlerin ortalamasını hesaplamayı başarabilirim, fakat Python'a nasıl yeni bir dizi döndüreceğimi gerçekten bilmiyorum. Okuduğum kaynaklardan, bence çok fazla tanıdık olmayan (ama bunu yapmaya istekli olan) işaretçilerle ve benzeri ciddi bir hokkabazlık gerektirir. Bugüne kadarC uzantısından dönen numpy dizisi

Kodum: I (yanılıyorsam beni düzeltin lütfen) bugüne kadar anlamaya ne

#include <Python.h> 
#include <numpy/arrayobject.h> 

// Actual magic here: 
static PyObject* 
myexts_std(PyObject *self, PyObject *args) 
{ 
    PyArrayObject *input=NULL; 
    int i, j, k, x, y, z, dims[2]; 
    double out = 0.0; 

    if (!PyArg_ParseTuple(args, "O!", &PyArray_Type, &input)) 
     return NULL; 

    x = input->dimensions[0]; 
    y = input->dimensions[1]; 
    z = input->dimensions[2]; 

    for(k=0;k<z;k++){ 
     for(j=0;j<y;j++){ 
      for(i=0;i < x; i++){ 
       out += *(double*)(input->data + i*input->strides[0] 
+j*input->strides[1] + k*input->strides[2]); 
      } 
     } 
    } 
    out /= x*y*z; 
    return Py_BuildValue("f", out); 
} 

// Methods table - this defines the interface to python by mapping names to 
// c-functions  
static PyMethodDef myextsMethods[] = { 
    {"std", myexts_std, METH_VARARGS, 
     "Calculate the standard deviation pixelwise."}, 
    {NULL, NULL, 0, NULL} 
}; 

PyMODINIT_FUNC initmyexts(void) 
{ 
    (void) Py_InitModule("myexts", myextsMethods); 
    import_array(); 
} 

ben (belki benim çıkış olacak olan yeni PyArrayObject oluşturmak için gereken olmasıdır PyArray_FromDims?). Sonra bu dizinin belleğine bir dizi adrese ihtiyacım var ve veri ile doldur. Bunun için nasıl giderim?

DÜZENLEME:

(burada: http://pw1.netcom.com/~tjensen/ptr/pointers.htm) işaretçiler biraz daha okuma yapıyor sonra ben amaçlayan ne elde etti. Şimdi başka bir soru ortaya çıkıyor: numpy.mean() 'nin oryantasyonel uygulamasını nerede bulabilirim? Nasıl olduğunu görmek istiyorum, python operasyonu versiyonumdan çok daha hızlı. Çirkin döngüden kaçındığını düşünüyorum. ;)

static PyObject* 
myexts_std(PyObject *self, PyObject *args) 
{ 
    PyArrayObject *input=NULL, *output=NULL; // will be pointer to actual numpy array ? 
    int i, j, k, x, y, z, dims[2]; // array dimensions ? 
    double *out = NULL; 
    if (!PyArg_ParseTuple(args, "O!", &PyArray_Type, &input)) 
     return NULL; 

    x = input->dimensions[0]; 
    y = dims[0] = input->dimensions[1]; 
    z = dims[1] = input->dimensions[2]; 
    output = PyArray_FromDims(2, dims, PyArray_DOUBLE);  
    for(k=0;k<z;k++){ 
     for(j=0;j<y;j++){ 
      out = output->data + j*output->strides[0] + k*output->strides[1]; 
      *out = 0; 
      for(i=0;i < x; i++){ 
       *out += *(double*)(input->data + i*input->strides[0] +j*input->strides[1] + k*input->strides[2]); 
      } 
      *out /= x; 
     } 
    } 
    return PyArray_Return(output); 
} 
+3


numpy ortalamasından için kaynak kodu: https://github.com/numpy/numpy/blob/3abd8699dc3c71e389356ca6d80a2cb9efa16151/numpy/core/src/multiarray/calculation.c#L744 – SingleNegationElimination

cevap

0

Numpy API "çirkin döngü" olmadan yapmaya çalıştığınız şeyi başarması bundan bir işlevi PyArray_Mean sahiptir:

İşte benim çözümdür. İşte