Numpy очень медленный для базовых операций с массивами - PullRequest
0 голосов
/ 08 апреля 2019

У меня есть код, в котором я делаю много основных арифметических вычислений с кучей числовых данных, которые являются множественными массивами.Я понял, что в большинстве возможных операций классы numpy всегда медленнее, чем классы Python по умолчанию.Почему это так?

Например, у меня есть простой фрагмент, где все, что я делаю, это просто обновляю 1 элемент массива numpy другим, полученным из другого массива numpy, или я обновляю его математическим произведением 2 других массивов numpyэлементы.Это должна быть базовая операция, но она всегда будет как минимум в 2-3 раза медленнее, чем если бы я делал это с list.

Сначала я подумал, что это потому, что я не гармонизировал структуры данных иКомпилятор должен сделать много ненужных преобразований.Затем я перекодировал все это и заменил все float на numpy.float64 и каждый list на numpy.ndarray, и все данные по всему коду numpy.float64, чтобы не было необходимости делать что-либо ненужноепреобразования.

Код все еще в 2-3 раза медленнее, чем если бы я просто использовал list и float.

Например:

    ALPHA       = [[random.uniform(*a_param)    for k in range(l2)] for l in range(l1)]
    COEFF       = [[random.uniform(*c_param)    for k in range(l2)] for l in range(l1)]

    summa=0.0
    for l in range(l1):
        for k in range(l2):
            summa+=COEFF[l][k] * ALPHA[l][k]

всегда будетБыть в 2-3 раза быстрее, чем:

    ALPHA       = numpy.random.uniform(*a_param, (l1,l2))
    COEFF       = numpy.random.uniform(*c_param, (l1,l2))

    summa=0.0
    for l in range(l1):
        for k in range(l2):
            summa+=COEFF[l][k] * ALPHA[l][k]

Как это возможно, я делаю что-то не так, поскольку numpy должен ускорить процесс.

Для записи, которую я использую Python 3.5.3 и numpy (1.12.1), мне обновить?

Ответы [ 2 ]

1 голос
/ 08 апреля 2019

Изменение одного элемента массива NumPy не ожидается быстрее, чем изменение одного элемента списка Python. Ускорение использования NumPy происходит, когда вы выполняете «векторизованные» операции над целыми массивами (или подмножествами массивов). Попробуйте назначить первые 10000 элементов массива NumPy равными первым 10000 элементам другого и сравните это с использованием списков.

Если ваши данные и / или операции очень малы (один или несколько элементов), вам, вероятно, лучше не использовать NumPy.

0 голосов
/ 09 апреля 2019

Я попробовал две вещи:

  1. Запуск ваших двух блоков кода. Для меня они были примерно с одинаковой скоростью.
  2. Написание новой функции, которая использует векторизованную математику numpy. Это в несколько раз быстрее, чем другие методы.

Вот мои функции:

import numpy as np

def with_lists(l1, l2):
    ALPHA = [[random.uniform(0, 1) for k in range(l2)] for l in range(l1)]
    COEFF = [[random.uniform(0, 1) for k in range(l2)] for l in range(l1)]
    summa=0.0
    for l in range(l1):
        for k in range(l2):
            summa+=COEFF[l][k] * ALPHA[l][k]
    return summa

def with_arrays(l1, l2):
    ALPHA = np.random.uniform(size=(l1,l2))
    COEFF = np.random.uniform(size=(l1,l2))
    summa=0.0
    for l in range(l1):
        for k in range(l2):
            summa+=COEFF[l][k] * ALPHA[l][k]
    return summa

def with_ufunc(l1, l2):
    """Avoid the loop completely by exploitng numpy's
    elementwise math."""
    ALPHA = np.random.uniform(size=(l1,l2))
    COEFF = np.random.uniform(size=(l1,l2))
    return np.sum(COEFF * ALPHA)

Когда я сравниваю скорость (я использую магию %timeit в IPython), я получаю следующее:

>>> %timeit with_lists(10, 10)
107 µs ± 4.7 µs per loop (mean ± std. dev. of 7 runs, 10000 loops each)

>>> %timeit with_arrays(10, 10)
91.9 µs ± 10.5 µs per loop (mean ± std. dev. of 7 runs, 10000 loops each)

>>> %timeit with_ufunc(10, 10)
12.6 µs ± 589 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)

Третья функция без циклов, примерно в 10-30 раз быстрее на моем аппарате, в зависимости от значений l1 и l2.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...