使用C API访问NumPy数组的视图 在C++中编写的Python扩展模块中,我使用下面的代码片段将NUMPY数组转换成一个数组,用于代码的C++部分: static arma::mat convert pyarraytoarma(PyArrayObject*pyarr,int nrows,int ncols) { //检查尺寸是否符合我的预期。 如果(!checkPyArrayDimensions(pyarr、nrows、ncols))抛出错误的维度(); const std::vector dims=getPyArrayDimensions(pyarr);//使用API获取维度 PyArray_Descr*reqDescr=PyArray_DescrFromType(NPY_DOUBLE); 如果(reqDescr==NULL)抛出std::bad_alloc(); //根据Armadillo的要求将数组转换为Fortran顺序 PyArrayObject*cleanArr=(PyArrayObject*)PyArray_FromArray(pyarr,reqDescr, NPY_阵列_法拉利); 如果(cleanArr==NULL)抛出std::bad_alloc(); reqDescr=NULL;//来自DecrFromType的新引用被FromArray窃取 double*dataPtr=static_cast(PyArray_DATA(cleanArr)); arma::mat result(dataPtr,dims[0],dims[1],true);//这将从cleanArr复制数据 Py_DECREF(cleanArr); 返回结果; }
问题是,当我将NumPy数组的视图传递给它时(即使用C API访问NumPy数组的视图 在C++中编写的Python扩展模块中,我使用下面的代码片段将NUMPY数组转换成一个数组,用于代码的C++部分: static arma::mat convert pyarraytoarma(PyArrayObject*pyarr,int nrows,int ncols) { //检查尺寸是否符合我的预期。 如果(!checkPyArrayDimensions(pyarr、nrows、ncols))抛出错误的维度(); const std::vector dims=getPyArrayDimensions(pyarr);//使用API获取维度 PyArray_Descr*reqDescr=PyArray_DescrFromType(NPY_DOUBLE); 如果(reqDescr==NULL)抛出std::bad_alloc(); //根据Armadillo的要求将数组转换为Fortran顺序 PyArrayObject*cleanArr=(PyArrayObject*)PyArray_FromArray(pyarr,reqDescr, NPY_阵列_法拉利); 如果(cleanArr==NULL)抛出std::bad_alloc(); reqDescr=NULL;//来自DecrFromType的新引用被FromArray窃取 double*dataPtr=static_cast(PyArray_DATA(cleanArr)); arma::mat result(dataPtr,dims[0],dims[1],true);//这将从cleanArr复制数据 Py_DECREF(cleanArr); 返回结果; },python,python-3.x,numpy,armadillo,python-c-api,Python,Python 3.x,Numpy,Armadillo,Python C Api,问题是,当我将NumPy数组的视图传递给它时(即my_array[:,3]),它似乎无法正确处理底层C数组的步幅。根据输出,函数接收的数组pyarr似乎实际上是全基数组,而不是视图(或者至少当我使用PyArray\u data访问数据时,我似乎得到了一个指向全基数组的指针)。如果我将视图的副本传递给此函数(即,my_array[:,3].copy()),它将按预期工作,但我不想每次都要记住这样做 那么,有没有办法让PyArray\u FromArray只复制我想要的矩阵切片?我尝试使用标志NPY
my_array[:,3]
),它似乎无法正确处理底层C数组的步幅。根据输出,函数接收的数组pyarr
似乎实际上是全基数组,而不是视图(或者至少当我使用PyArray\u data
访问数据时,我似乎得到了一个指向全基数组的指针)。如果我将视图的副本传递给此函数(即,my_array[:,3].copy()
),它将按预期工作,但我不想每次都要记住这样做
那么,有没有办法让PyArray\u FromArray
只复制我想要的矩阵切片?我尝试使用标志NPY\u ARRAY\u ENSURECOPY
,但没有帮助
编辑1
正如评论中所建议的,以下是一个完整的工作示例:
在文件example.cpp
中:
#定义NPY#U否#U API NPY#U 1#U API#U版本
外部“C”{
#包括
#包括
}
#包括
#包括
#包括
#包括
#包括
#包括
#包括
类错误维度:公共标准::异常
{
公众:
错误维度(){}
const char*what()const noexcept{return msg.c_str();}
私人:
std::string msg=“尺寸不正确”;
};
类NotImplemented:public std::exception
{
公众:
NotImplemented(){}
const char*what()const noexcept{return msg.c_str();}
私人:
std::string msg=“未实现”;
};
类BadArrayLayout:public std::exception
{
公众:
BadArrayLayout(){}
const char*what()const noexcept{return msg.c_str();}
私人:
std::string msg=“矩阵不连续”;
};
静态常量std::vector getPyArrayDimensions(PyArrayObject*pyarr)
{
npy_intp ndims=PyArray_NDIM(pyarr);
npy_intp*dims=PyArray_形状(pyarr);
std::向量结果;
对于(int i=0;ifrom 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')
>>> example.test_function(a[:, 3])
array([ 4., 5., 6.])
>>> example.test_function(a[:, 3].copy())
array([ 4., 10., 16.])