Программа Cython с массивами numpy не допускает вложенных входов (только принимает длину 1 массив), как исправить?

FIXED: см. Обновленный код ниже.

Это моя первая попытка Cython и рабочая сборка, но она не позволяет использовать массив numpy (векторы) в качестве исходных данных, что является моей реальной целью здесь. Это черная модель (Black Scholes для европейских опционов без дивидендов). Он будет принимать только длины 1 массивов в качестве входов (если я попытаюсь вычислить с длиной 2 массива его ошибки: TypeError: CyBlack() takes exactly 7 positional arguments (14 given) , если я передаю длину 10 массивов (70 given) и т. Д. .). Я не уверен, почему, поскольку я определил массивы numpy в коде Cython. Для справки вы можете скомпилировать его с помощью приведенного ниже кода, а затем использовать его как таковой: from CyBlack.CyBlack import CyBlack затем вызывать CyBlack(BlackPnL, Black_S, Black_Texpiry, Black_strike, Black_volatility, Black_IR, Black_callput) Итак, вот код (сохранить как CyBlack.pyx файл для компиляции):

 from numpy cimport ndarray cimport numpy as np cimport cython cdef extern from "math.h": double exp(double) double sqrt(double) double log(double) double erf(double) cdef double std_norm_cdf(double x): return 0.5*(1+erf(x/sqrt(2.0))) @cython.boundscheck(False) cpdef CyBlack(ndarray[np.float64_t, ndim=1] BlackPnL, ndarray[np.float64_t, ndim=1] Black_S, ndarray[np.float64_t, ndim=1] Black_Texpiry, ndarray[np.float64_t, ndim=1] Black_strike, ndarray [np.float64_t, ndim=1] Black_volatility, ndarray[np.float64_t, ndim=1] Black_IR, ndarray[np.int64_t, ndim=1] Black_callput): cdef Py_ssize_t i cdef Py_ssize_t N = BlackPnL.shape[0] cdef double d1, d2 for i in range(N): d1 = ((log(Black_S[i] / Black_strike[i]) + Black_Texpiry[i] * Black_volatility[i] **2 / 2)) / (Black_volatility[i] * sqrt(Black_Texpiry[i])) d2 = d1 - Black_volatility[i] * sqrt(Black_Texpiry[i]) BlackPnL[i] = exp(-Black_IR[i] * Black_Texpiry[i]) * (Black_callput[i] * Black_S[i] * std_norm_cdf(Black_callput[i] * d1) - Black_callput[i] * Black_strike[i] * std_norm_cdf(Black_callput[i] * d2)) return BlackPnL 

Вот setup.py чтобы другие могли построить эту типизацию: python setup.py build_ext --inplace построенный с VS2015 для Python 3.5 64-битной Windows.

 from distutils.core import setup from Cython.Build import cythonize import numpy extra_compile_args = ['/EHsc', '/openmp', '/favor:INTEL64'] setup( ext_modules=cythonize("CyBlack.pyx"), include_dirs=['.', numpy.get_include()], extra_compile_args=extra_compile_args) 

Вышеприведенное компилируется и работает после использования исправления типа переменной (Black_callput на самом деле является int64 ), и вам необходимо передать массивы numpy, как они есть (нет звезды), и он работает правильно.

One Solution collect form web for “Программа Cython с массивами numpy не допускает вложенных входов (только принимает длину 1 массив), как исправить?”

Здесь было два вопроса:

  1. TypeError: CyBlack() takes exactly 7 positional arguments (14 given)

    Это было вызвано тем фактом, что вы распаковывали свои входные массивы с помощью оператора * («splat»). Вам нужно было передать их как 7 отдельных аргументов.

  2. ValueError: Buffer dtype mismatch, expected 'float64_t' but got 'long long' :

    Эта ошибка говорила вам, что один из входных массивов имел long long тип C (который представляет собой 64-битное целое число), а не float64_t как указано в объявлениях типа ввода. Вам нужно было np.float64 все ваши входные массивы в np.float64 .

Interesting Posts

Можно ли определить способ импорта модуля в python?

Быстрый доступ к строке в файле Python

Как удалить элементы leftmost / rightmost в списке, которые удовлетворяют определенному критерию в python?

Когда python выбирает ставить строку

Ошибка слияния PyPdf

использование Word2VecModel.transform () не работает в функции карты

Как работает длительный опрос в «Торнадо»?

Как преобразовать некоторый символ в пятизначный unicode в Python 3.3?

Python Matplotlib зависает, когда его попросят построить второй график (после закрытия первого окна графика)

Использование argparse с функцией, которая принимает аргумент ** kwargs

Перегрузка (или альтернативы) в дизайне API Python

Панды: медленное преобразование даты

Может ли SQLAlchemy использоваться с Google Cloud SQL?

Запуск нескольких находок и замещений в Python (для каждого файла в папке и подпапке)

Как создать сокет IPv6 на python? Зачем нужен socket.error: (22, 'Invalid argument')?

Python - лучший язык программирования в мире.