2011-10-18 15 views
1

我在这里呕吐,希望有人能够充分了解Numpy的C API中新的NpyIter API,以便快速告诉我我做错了什么。如何使用NpyIter(新API)直接访问数据?我该如何处理char *类型?

我有一个形状(真的很大,有点大)的数组。元素是双打> = 0。对于每一行,我需要找到总和为最大值的连续非零值的总和。我不知道有什么方法可以在Python中很快完成此操作(有时真的很大),所以我一直在使用Weave。

在我以前的代码,我有以下几点:

  double *p1,*res; 
      double g,d,q; 
      PyArrayIterObject *itr; 
      int axis = 1; 
      g = 0; 
      d = 0; 
      itr = (PyArrayIterObject *) PyArray_IterAllButAxis(py_x,&axis); 
      while(PyArray_ITER_NOTDONE(itr)) { 
       const int go = x_array->strides[axis]/sizeof(double); 
       p1 = (double *) PyArray_ITER_DATA(itr); 
       res = (double *) PyArray_GETPTR1(py_r,itr->index); 
       g = 0; 
       d = 0; 
       for (int i = 0; i < x_array->dimensions[axis]; i++) { 
        d+=*p1; 
        if (d>g) g=d; 
        if ((*p1)==0) d=0; 
        p1+=go; 
       } 
       *res = g; 
       PyArray_ITER_NEXT(itr); 
      } 
      PyArray_free(itr); 

这工作,但它非常泄漏内存。我不知道如何防止泄漏,旧的PyArrayIter的文档在内存管理方面相当缺乏。

我试着用NpyIter API编写新代码,但是对于那些在内存管理方面缺少的东西其他。具体来说,我并不完全确定我应该如何访问实际的数组值。我已经试过如下:

  char *p1; 
      double *res; 
      char **p1p; 
      double g,d,q; 
      int go; 
      NpyIter* iter; 
      NpyIter_IterNextFunc *iternext; 
      g = 0; 
      d = 0; 
      iter = NpyIter_New(x_array, NPY_ITER_READONLY|NPY_ITER_EXTERNAL_LOOP, NPY_KEEPORDER, NPY_NO_CASTING, NULL); 
      iternext = NpyIter_GetIterNext(iter, NULL); 
      p1p = NpyIter_GetDataPtrArray(iter); 

      do { 
       p1 = *p1p; 
       const int go = x_array->strides[1]/sizeof(double); 
       res = (double *) PyArray_GETPTR1(py_r,NpyIter_GetIterIndex(iter)); 
       g = 0; 
       d = 0; 
       for (int i = 0; i < x_array->dimensions[1]; i++) { 
        d+= p1; 
        if (d>g) g=d; 
        if ((*p1)==0) d=0; 
        p1+=go; 
       } 
       *res = g; 
      } while(iternext(iter)); 

      NpyIter_Deallocate(iter); 

不过,这显然没有因为焦炭的工作*与双*。我不知道,但是,如何走(字符**)从NpyIter_GetDataPtrArray返回,并把它变成实际的数组值:文档极其帮倒忙而是使用没有给出一个函数,需要一个char *。

我该如何做到这一点,并且不会泄漏内存?

+0

我从来没有使用NPyIter api,但是有没有一个原因,你不能直接访问内存?使用cyppe和numpy数组我有很多的喜悦。它通常只是一块内存。 –

回答

2

在第一种情况下,您需要遵循通常的PyObject内存管理规则:使用后Py_DECREF您的PyArrayIterObject以避免内存泄漏。 (PyArray_free做完全不同的东西。)

对于NpyIter

要访问数据,抢(double*)(*dataptr)

如果您完全不知道自己在做什么,请不要使用NPY_ITER_EXTERNAL_LOOP。要复制的IterAllButAxis行为,需要调用NpyIter_RemoveAxis删除您不想从迭代遍历轴。

相关问题