У меня есть библиотека на c ++, и я пытаюсь обернуть ее для python, используя Cython.Одна функция возвращает массив трехмерных векторов (float (* x) [3]), и я хочу получить доступ к этим данным из python.Я мог сделать это, выполнив что-то вроде
res = [
(self.thisptr.x[j][0],self.thisptr.x[j][1],self.thisptr.x[j][2])
for j in xrange(self.natoms)
]
, но я хотел бы получить доступ к нему как к массиву numpy, поэтому я попытался использовать numpy.array, и это было намного медленнее.Я также пытался
cdef np.ndarray res = np.zeros([self.thisptr.natoms,3], dtype=np.float)
cdef int i
for i in range(self.natoms):
res[i][0] = self.thisptr.x[i][0]
res[i][1] = self.thisptr.x[i][1]
res[i][2] = self.thisptr.x[i][2]
Но примерно в три раза медленнее, чем версия списка.
Есть ли какие-либо предложения о том, как быстрее преобразовать список векторов в простой массив?
Полный код
cimport cython
import numpy as np
cimport numpy as np
ctypedef np.float_t ftype_t
cdef extern from "ccxtc.h" namespace "ccxtc":
cdef cppclass xtc:
xtc(char []) except +
int next()
int natoms
float (*x)[3]
float time
cdef class pyxtc:
cdef xtc *thisptr
def __cinit__(self, char fname[]):
self.thisptr = new xtc(fname)
def __dealloc__(self):
del self.thisptr
property natoms:
def __get__(self):
return self.thisptr.natoms
property x:
def __get__(self):
cdef np.ndarray res = np.zeros([self.thisptr.natoms,3], dtype=np.float)
cdef int i
for i in range(self.natoms):
res[i][0] = self.thisptr.x[i][0]
res[i][1] = self.thisptr.x[i][1]
res[i][2] = self.thisptr.x[i][2]
return res
#return [ (self.thisptr.x[j][0],self.thisptr.x[j][1],self.thisptr.x[j][2]) for j in xrange(self.natoms)]
@cython.boundscheck(False)
def next(self):
return self.thisptr.next()