Numba @jit не может ускорить выполнение этой функции.В любом случае, чтобы это исправить? - PullRequest
0 голосов
/ 21 октября 2018

Я новичок в пакете numba в python.Я не уверен, правильно ли я использую numba.jit, но код работает слишком медленно с 23,7 с за цикл по строке: Z1 = mmd (X, Y, 20). Как правильно оптимизировать код?Мне нужна ваша помощь, ребята.Спасибо.

Вот мой код:

import pandas as pd
import numba as nb
import numpy as np
@nb.jit
def mmd(array1, array2, n):
    n1 = array1.shape[0]
    MMD = np.empty(n1, dtype = 'float64')

    for i in range(n-1,n1):
        MMD[i] = np.average(abs(array1[i+1-n:i+1] - array2[i]))

    return MMD

X = np.array([i**2 for i in range(1000000)])
Y = np.array([i for i in range(1000000)])
Z1 = mmd(X,Y,20)

РЕДАКТИРОВАТЬ: еще больше упростил код

РЕДАКТИРОВАТЬ 2: пробовал @ nb.jit (nopython = True), затемпоявляется сообщение об ошибке:

KeyError: "<class 'numba.targets.cpu.CPUTargetOptions'> does not support option: 'nonpython'"

также попытался:

@nb.jit(nb.float32[:](nb.float32[:],nb.float32[:],nb.int8))

1 Ответ

0 голосов
/ 21 октября 2018

Чтобы Numba работала хорошо, вам нужно использовать режим "nopython", как вы упоминали.Чтобы включить это, просто запустите программу с jit, замененным на njit (или, что эквивалентно, jit(nopython=True), и исправьте ошибки одну за другой:

  1. np.empty () неподдерживает аргумент dtype='float64' в Numba. Это нормально, потому что float64 является значением по умолчанию. Просто удалите его.
  2. np.average () не поддерживается в Numba. Это нормально, так как мы не передаем весовв любом случае, это то же самое, что np.mean (). Замените его.
  3. Встроенный abs () не поддерживается в Numba. Вместо этого используйте np.abs ().

В итоге мы получим следующее:

@nb.njit
def mmd(array1, array2, n):
    n1 = array1.shape[0]
    MMD = np.empty(n1)

    for i in range(n-1,n1):
        MMD[i] = np.mean(np.abs(array1[i+1-n:i+1] - array2[i]))

    return MMD

И это в 100 раз быстрее.

Бонусные советы:

  1. Вы можете инициализировать данные своего образца подробнеекратко и быстро, как это:

    Y = np.arange(1000000)
    X = Y * Y
    
  2. Первые n значений в результате - неинициализированный мусор. Возможно, вы захотите его как-то очистить.

...