如何使用SWIG将numpy数组转换为vector <int>&(reference) - python

我的目标:

在python中创建3个numpy数组(其中2个将使用特定的值初始化),然后将所有三个通过swig发送到c ++函数中作为矢量引用(这是为了避免复制数据和失去效率)。一旦进入c ++函数,就将两个数组相加,并将它们的总和放在第三个数组中。

vec_ref.h

#include <vector>
#include <iostream>

void add_vec_ref(std::vector<int>& dst, std::vector<int>& src1, std::vector<int>& src2);

vec_ref.cpp

#include "vec_ref.h"
#include <cstring> // need for size_t
#include <cassert>

void add_vec_ref(std::vector<int>& dst, std::vector<int>& src1, std::vector<int>& src2) {
    std::cout << "inside add_vec_ref" << std::endl;
    assert(src1.size() == src2.size());
    dst.resize(src1.size());

    for (size_t i = 0; i < src1.size(); i++) {
        dst[i] = src1[i] + src2[i];
    }
}

vec_ref.i

%module vec_ref
%{
    #define SWIG_FILE_WITH_INIT
    #include "vec_ref.h"
%}

%include "numpy.i"
%init %{
import_array();
%}

%include "std_vector.i"
%template(vecInt) std::vector<int>;
// %template(vecIntRef) std::vector<int> &; 

// %apply (std::vector<int> * INPLACE_ARRAY1, int DIM1) {(std::vector<int> * dst, int a),(std::vector<int> * src1, int b),(std::vector<int> * src2, int c)};
// %apply (std::vector<int> * INPLACE_ARRAY1) {(std::vector<int> * dst),(std::vector<int> * src1),(std::vector<int> * src2)};
// %apply (std::vector<int> & INPLACE_ARRAY1) {(std::vector<int> & dst),(std::vector<int> & src1),(std::vector<int> & src2)};
// %apply (std::vector<int> & INPLACE_ARRAY1, int DIM1) {(std::vector<int> & dst, int a),(std::vector<int> & src1, int b),(std::vector<int> & src2, int c)};

%include "vec_ref.h"

生成文件

all:
    rm -f *.so *.o *_wrap.* *.pyc *.gch vec_ref.py
    swig -c++ -python vec_ref.i
    g++ -O0 -g3 -fpic -c vec_ref_wrap.cxx vec_ref.h vec_ref.cpp -I/home/lmckeereid/tools/anaconda3/pkgs/python-3.7.3-h0371630_0/include/python3.7m/
    g++ -O0 -g3 -shared vec_ref_wrap.o vec_ref.o -o _vec_ref.so

测试器

import vec_ref as vec
import numpy as np

a = np.array([1,2,3], dtype=np.intc)
b = np.array([4,5,6], dtype=np.intc)
c = np.zeros(len(a), dtype=np.intc)

print('---Before---\na:', a)
print('b:', b)
print('c:', c)

vec.add_vec_ref(c,a,b)

print('---After---\na:', a)
print('b:', b)
print('c:', c)

输出:

---Before---
a: [1 2 3]
b: [4 5 6]
c: [0 0 0]
Traceback (most recent call last):
  File "tester.py", line 12, in <module>
    vec.add_vec_ref(c,a,b)
TypeError: in method 'add_vec_ref', argument 1 of type 'std::vector< int,std::allocator< int > > &'

我已经尝试了在vec_ref.i中找到的所有注释掉的%apply和%template指令,但是它们没有用。

有没有我应该包括的一些类型映射?

参考方案

我同意@pschill:如果不复制数据就无法获得std :: vector。

一种替代方法是使用std::span class template(在C ++ 20中引入),或使用库中定义的类似span类模板。

创建std::span<int>将提供numpy数组中现有数据的视图,并在C ++中提供many convenient member functions(例如operator[],迭代器,front()back()等)。

创建范围将永远不会从numpy数组中复制数据。

Python numpy数据指针地址无需更改即可更改 - python

编辑经过一些摆弄之后,到目前为止,我已经隔离了以下状态:一维数组在直接输入变量时提供两个不同的地址,而在使用print()时仅提供一个地址2D数组(或矩阵)在直接输入变量时提供三个不同的地址,在使用print()时提供两个地址3D数组在直接输入变量时提供两个不同的地址,而在使用print()时仅给出一个(显然与一维数组相同)像这样:>>> …

Python Pandas导出数据 - python

我正在使用python pandas处理一些数据。我已使用以下代码将数据导出到excel文件。writer = pd.ExcelWriter('Data.xlsx'); wrong_data.to_excel(writer,"Names which are wrong", index = False); writer.…

在节点有数据的地方绘制图形 - python

我有一个包含一些复杂数据的有向图。我想绘制此图并将每个节点表示为一个表。有没有办法做到这一点?我发现的所有绘图示例都只有一个标签或一些简单地绘制到节点中的示例。仅供参考:我目前正在使用networkx 参考方案 使用graphviz时,标签可以代表更复杂的东西,例如表格。Graphviz提供两种变体:Record based nodes基于记录的节点提供了一…

按列名称显示的Python Selenium复制表列 - python

我有一个包含这些标题的表,如下所示:如何使用xpath选择整列存储在数组中。我希望使用不同的数组,例如:courses = [] teacher = [] avg = [] 请记住,这些列没有任何ID或类,因此我需要一种仅使用列名进行选择的方法。这是表格的代码:<table border="0"> <tbody> …

合并List <T>和List <Optional <T >> - java

鉴于: List<Integer> integers = new ArrayList<>(Arrays.asList( 10, 12 )); List<Optional<Integer>> optionalIntegers = Arrays.asList( Optional.of(5), Optional.em…