2013-07-10 3 views
7

В моем коде я использую массивы numpy для взаимодействия между методами и классами. Оптимизируя основные части моей программы, я использую cython с c указателями этих массивов numpy. К сожалению, способ, которым я сейчас объявляю массивы, довольно длинный.Объявление массива numpy и c-указателя в cython

Например, у меня есть метод, который должен возвращать массив numpyrayArrayNumpy, но внутри указателей на функцию * someArrayPointers следует использовать для скорости. Это, как я обычно объявляю:

cdef: 
    numpy.ndarray someArrayNumpy = numpy.zeros(someArraySize) 
    numpy.ndarray[numpy.double_t, ndim=1] someArrayBuff = someArrayNumpy 
    double *someArrayPointers = <double *> someArrayBuff.data 

[... some Code ...] 

return someArrayNumpy 

Как вы можете видеть, это занимает 3 строки кода для одного массива в основном, и часто я должен объявить более из этих массивов.

Есть ли более компактный/умный способ сделать это? Я думаю, что чего-то не хватает.

EDIT:

Так, потому что это было предложено Дж Martinot-Лагард я приуроченная указатели C и "Numpy указатели". Код был в основном

for ii in range(someArraySize): 
    someArrayPointers[ii] += 1 

и

for ii in range(someArraySize): 
    someArrayBuff[ii] += 1 

с определениями из выше, но я добавил "ndim = 1, режим = 'с'", просто чтобы убедиться. Результаты для someArraySize = 1E8 (время в мс):

testMartinot("cPointers") 
531.276941299 
testMartinot("numpyPointers") 
498.730182648 

Вот что я примерно помню из предыдущих/различных критериев.

+0

Если кто-нибудь читает это: К настоящему моменту я перешел к использованию типизированных представлений памяти cython. По моему опыту они очень близки к показателям C в производительности (ближе, чем к буферу numpy) и намного проще в использовании. Фактически, в некоторых редких случаях я делал «маленькие» (таким образом, не легко узнаваемые/избегаемые) ошибки с C-указателями, которые делали их медленнее, чем типизированные представления памяти. Я действительно рекомендую вводить данные в память, если и где это возможно. – oli

ответ

5

Вы на самом деле объявляете здесь два массива numpy, первый из которых является общим, а второй имеет определенный тип dtype. Вы можете пропустить первую строку, someArrayBuff - это ndarray.

Это дает:

numpy.ndarray[numpy.double_t] someArrayNumpy = numpy.zeros(someArraySize) 
double *someArrayPointers = <double *> someArrayNumpy.data 

Вам нужно по крайней мере две строки, потому что вы используете someArrayPointers и возвращение someArrayNumpy так что вы должны объявить их.


В качестве примечания, вы уверены, что указатели быстрее, чем ndarrays, если объявить тип и количество измерений массива?

numpy.ndarray[numpy.double_t, ndim=2] someArrayNumpy = numpy.zeros(someArraySize) 
+0

Спасибо за ваш ответ, я как-то подумал, что материал numpy.dtype_t является необходимым буфером. Btw Я добавил несколько timit выше, чтобы оправдать использование C-указателей. Это не так много, но в моем случае общая> 5% -ная скорость стоит того. – oli

+0

Спасибо за тесты! –

Смежные вопросы