在C++中编写的Python扩展模块中,我使用以下代码片段将NUMPY数组转换成Armadillo数组,用于代码的C++部分:
static arma::mat convertPyArrayToArma(PyArrayObject* pyarr, int nrows, int ncols)
{
// Check if the dimensions are what I expect.
if (!checkPyArrayDimensions(pyarr, nrows, ncols)) throw WrongDimensions();
const std::vector<int> dims = getPyArrayDimensions(pyarr); // Gets the dimensions using the API
PyArray_Descr* reqDescr = PyArray_DescrFromType(NPY_DOUBLE);
if (reqDescr == NULL) throw std::bad_alloc();
// Convert the array to Fortran-ordering as required by Armadillo
PyArrayObject* cleanArr = (PyArrayObject*)PyArray_FromArray(pyarr, reqDescr,
NPY_ARRAY_FARRAY);
if (cleanArr == NULL) throw std::bad_alloc();
reqDescr = NULL; // The new reference from DescrFromType was stolen by FromArray
double* dataPtr = static_cast<double*>(PyArray_DATA(cleanArr));
arma::mat result (dataPtr, dims[0], dims[1], true); // this copies the data from cleanArr
Py_DECREF(cleanArr);
return result;
}
问题是,当我传递NumPy数组的这个视图时(即my_array[:, 3]
),它似乎不能正确地处理底层C数组的跨步。根据输出,函数接收的数组pyarr
实际上是完整的基数组,而不是视图(或者至少当我使用PyArray_DATA
访问数据时,我似乎得到了一个指向完整基数组的指针)。如果我给这个函数传递一个视图的副本(即my_array[:, 3].copy()
),它会按预期工作,但我不想每次都记住这样做。在
那么,有没有办法让PyArray_FromArray
只复制我想要的矩阵的切片?我试着使用标志NPY_ARRAY_ENSURECOPY
,但没用。在
正如评论中所建议的,下面是一个完整的工作示例:
在文件example.cpp
中:
和setup.py
用于编译:
from setuptools import setup, Extension
import numpy as np
example_module = Extension(
'example',
include_dirs=[np.get_include(), '/usr/local/include'],
libraries=['armadillo'],
library_dirs=['/usr/local/lib'],
sources=['example.cpp'],
language='c++',
extra_compile_args=['-std=c++11', '-mmacosx-version-min=10.10'],
)
setup(name='example',
ext_modules=[example_module],
)
现在假设我们有一个示例数组
a = np.array([[ 1, 2, 3, 4, 5, 6],
[ 7, 8, 9,10,11,12],
[13,14,15,16,17,18]], dtype='float64')
该函数对于多维切片(如a[:, :3]
)似乎可以很好地工作,并且它像我预期的那样原封不动地返回矩阵。但是如果我给它一个一维切片,除非我复制一个,否则我得到了错误的组件:
>>> example.test_function(a[:, 3])
array([ 4., 5., 6.])
>>> example.test_function(a[:, 3].copy())
array([ 4., 10., 16.])
数组视图只是同一数据数组的另一个信息包装器。
Numpy
不在此处复制任何数据。仅调整用于解释数据的信息,如果有用,则移动指向数据的指针。在在您的代码中,假设向量}来说没有区别。但是这个表示只有在创建数组本身的(fortran排序的)副本之后才能得到。在
a[:, 3]
的数据表示为内存中的一个向量,对于NPY_ARRAY_CARRAY
和{为了使其工作,我修改了您的
convertPyArrayToArma()
函数,以创建一个副本,即使它是一个向量:相关问题 更多 >
编程相关推荐