将std::vector转换为NumPy数组而不复制数据
Convert a std::vector to a NumPy array without copying data
我有一个c++库,其中目前有一些方法返回std::vector
定义,如
public:
const std::vector<uint32_t>& getValues() const;
我目前正在使用SWIG包装Python的整个库,到目前为止工作得很好。
SWIG很好地包装了这个getValues()
函数,使得它返回一个Python元组。问题是在我的python端代码中,我想将其转换为NumPy数组。当然,我可以这样做:
my_array = np.array(my_object.getValues(), dtype='uint32')
,但这会导致原始向量中的所有条目首先被SWIG复制到Python元组中,然后再被我复制到numpy数组中。由于这个向量可能非常大,我宁愿避免制作这两个副本,并希望有一种方法让SWIG创建一个numpy。内存中原始矢量数据的数组包装。
我已经阅读了numpy的文档。i,但它明确提到不支持输出数组,因为它们似乎在C风格数组而不是c++向量的假设下工作。
numpy。数组的底层数据结构只是一个C风格的数组,也是一个c++ std::vector,所以我希望它是可行的,然后访问内存中的相同数据。
是否有办法使SWIG返回一个numpy。数组不复制原始数据?
显然,将c++向量"强制转换"为(C)数组是微不足道的,参见这个问题的答案:如何在c++中将向量转换为数组
接下来,你可以创建一个numpy数组,它将使用C数组而不复制,参见这里的讨论,或谷歌PyArray_SimpleNewFromData
。
我不希望SWIG自动为您完成所有这些工作,相反,您应该自己为函数getValues
编写一个包装器,例如getValuesAsNumPyArray
。
似乎PyArray_SimpleNewFromData
需要你做你自己的内存管理;如果内存管理已经在c++端处理了,也就是说,Python不负责内存,你可以使用np.asarray
来获得一个numpy数组,它与c++向量共享内存,如下所示:
from libcpp.vector cimport vector
import numpy as np
cdef vector[double] vec
vec.push_back(1)
vec.push_back(2)
cdef double *vec_ptr = &vec[0] # get hold of data array underlying vec; also vec.data() if you have C++11
cdef double[::1] vec_view = <double[:vec.size()]>vec_ptr # cast to typed memory view
vec_npr = np.asarray(vec_view) # get numpy array from memory view
print(vec_npr) # array([1.0, 2.0])
Kurt Smith的Cython书籍第10章中的"包装C和c++数组"一节提供了很好的示例。请参见官方用户指南中的强制转换到Numpy。
- 在数组中使用C++中的哈希表复制数组中的元素
- 快速复制数组到阵列
- 如何在C 中复制数组
- 赋值运算符复制数组中除可用空间之外的所有内容
- 尝试复制数组时从 DLL 调用函数时程序崩溃
- 反向复制数组
- 复制数组 - 将数组加倍后崩溃
- 复制数组和气泡排序 C++
- 在结构中复制构造函数:是否复制数组
- 如何从类中复制数组并将新数组的大小加倍
- 在C++中复制数组的麻烦
- 逐行复制数组的内容
- tictactoe和复制数组
- 正在使用数组的名称strring复制数组
- c++复制数组到数组
- . net互操作是来回复制数组数据,还是固定数组?
- 从通过函数发送的结构体中复制数组
- 使用CUDA Thrust置换迭代器复制数组的特定元素
- C/ c++中有复制数组的函数吗?
- 在引用中复制数组