2013-04-17 1 views
9

나는 C 현재 몇 가지 방법을 가지고 ++ 라이브러리를 복사하지 않고 NumPy와 배열에 표준 : : 벡터 변환 나는 현재 전체 라이브러리를 포장하고 있어요 std::vector 정의 하는 내부 반환 데이터

public: 
    const std::vector<uint32_t>& getValues() const; 

같은 SWIG를 사용하는 Python의 경우 이것은 지금까지 잘 작동합니다.

SWIG는이 getValues() 함수가 파이썬 튜플을 반환하도록 잘게 래핑합니다. 문제는 파이썬 측 코드에서 이것을 NumPy 배열로 변환하려고합니다. 물론 나는이 작업을 수행 할 수 있습니다 :

my_array = np.array(my_object.getValues(), dtype='uint32') 

그러나 이것은 원래 벡터의 모든 항목이 나를 먼저하여 NumPy와 배열에 다시 꿀꺽 꿀꺽하여 파이썬 튜플에 복사되도록합니다. 이 벡터는 매우 클 수 있기 때문에 차라리이 두 복사본을 만드는 것을 피하고 SWIG에서 메모리의 원래 벡터 데이터 주위에 numpy.array 래퍼를 만드는 방법을 원합니다.

numpy.i에 대한 설명서를 읽었지만 출력 배열이 C++ 벡터가 아닌 C 스타일 배열을 전제로 작동하고 있기 때문에 출력 배열이 지원되지 않는다고 명시 적으로 언급합니다.

numpy.array의 기본 데이터 구조는 C++ std :: vector와 마찬가지로 C 스타일의 배열이므로 메모리의 동일한 데이터에 액세스 할 수 있기를 바랍니다.

SWIG가 원래 데이터를 복사하지 않는 numpy.array를 반환 할 수있는 방법이 있습니까?

답변

8

은 분명히이 (C) 배열에 C++ 벡터 "캐스트"에 사소한,이 질문에 대한 답을 참조하십시오 How to convert vector to array in C++

다음은 복사하지 않고 그 C 배열을 사용하는 NumPy와 배열을 만들 수 discussion here 참조 또는 PyArray_SimpleNewFromData에 대해 google을 사용하십시오.

SWIG가 자동으로이 모든 작업을 수행 할 것으로 기대하지는 않지만 대신 과 같은 함수 getValues에 대한 래퍼를 작성해야합니다.

0

PyArray_SimpleNewFromData처럼 자신의 메모리 관리가 필요합니다.

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]) 

: 메모리 관리가 이미 C++ 측에서 처리 된 경우, 즉, 파이썬은 당신이 단지는 C++ 벡터와 메모리를 공유하므로 같은 NumPy와 배열을 얻을 수 np.asarray를 사용하여, 메모리에 대한 책임을지지 않습니다 커트 스미스 (Kurt Smith)의 Cython 서 10 장에있는 "C 및 C++ 배열 배치"섹션은 이에 대한 좋은 예를 제공합니다. 또한 Coercion to Numpy from official user guide을 참조하십시오.

+0

이로 인해 파이썬이 나에게 충돌을 일으켰습니다. – snowleopard