Ускорение циклов по массиву Numpy

В моем коде у меня есть цикл, который индексирует многомерный массив numpy и выполняет некоторую операцию с использованием подматрицы, которая получается на каждой итерации. Похоже, это

for sub in Arr: #do stuff using sub 

Теперь материал, который делается с помощью sub , полностью векторизован, поэтому он должен быть эффективным. С другой стороны, эта петля повторяется примерно в ~10^5 раз и является узким местом. Думаете ли вы, что я получу улучшение, выгрузив эту часть на C. Я немного неохотно это делаю, потому что do stuff using sub вещания, нарезки, умных индексирующих трюков, которые были бы утомительными для написания на простом C. Я бы тоже приветствовать мысли и предложения о том, как бороться с трансляцией, нарезкой, интеллектуальным индексированием при выгрузке вычислений на C.

3 Solutions collect form web for “Ускорение циклов по массиву Numpy”

Сан вы можете взглянуть на scipy.weave . Вы можете использовать scipy.weave.blitz чтобы трансформировать ваше выражение в код C++ и запустить его. Он будет обрабатывать резки автоматически и избавиться от временных, но вы утверждаете, что тело вашего цикла for не создает временные интервалы, поэтому ваше перемещение может отличаться.

Однако, если вы хотите заменить весь цикл for на что-то более эффективное, вы можете использовать scipy.inline . Недостатком является то, что вам нужно написать код на C++ . Это не должно быть слишком сложно, потому что вы можете использовать синтаксис Blitz++ который очень близок к выражениям массива numpy. Нарезка поддерживается напрямую, однако вещание – нет.

Есть две работы:

  1. заключается в использовании numpy-C api и использовании многомерных итераторов. Они прозрачно обрабатывают вещание. Однако вы вызываете среду выполнения Numpy, поэтому могут возникнуть некоторые накладные расходы. Другой вариант и, возможно, более простой вариант – использовать стандартную матричную нотацию для трансляции. Трансляционные операции могут быть записаны как внешние продукты с вектором всех единиц. Хорошо, что Blitz++ самом деле не создаст эти временные широковещательные массивы в памяти, он выяснит, как превратить его в эквивалентный цикл.

  2. Для второго варианта ознакомьтесь с http://www.oonumerics.org/blitz/docs/blitz_3.html#SEC88 для владельцев индексных площадок. Пока ваша матрица имеет менее 11 размеров, вы в порядке. Эта ссылка показывает, как их можно использовать для создания внешних продуктов http://www.oonumerics.org/blitz/docs/blitz_3.html#SEC99 (поиск внешних продуктов для перехода к соответствующей части документа).

Если вы не можете «векторизовать» всю операцию, и цикл является действительно узким местом, я настоятельно рекомендую использовать Cython. Я недавно занимался этим, и с ним просто работать, и у него есть достойный интерфейс с numpy. Для чего-то вроде интегратора langevin я видел 115-кратное ускорение над достойной реализацией в numpy. Смотрите документацию здесь:

http://docs.cython.org/src/tutorial/numpy.html

и я также рекомендую посмотреть следующую статью

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

Помимо использования Cython, вы можете написать часть (-и) бутылочки в Фортране. Затем используйте f2py, чтобы скомпилировать его в файл Python .pyd.

  • Как найти парные различия между строками двух очень больших матриц с использованием numpy?
  • Map numpy `in1d` над двумерным массивом
  • Код выхода 139 при выполнении вычитания изображения
  • Enthought Python, Sage или другие (в Unix-кластерах)
  • Numpy isnan () терпит неудачу в массиве поплавков (из приложения pandas dataframe)
  • Генерация случайных чисел с заданной функцией плотности
  • Спектр мощности и автокорреляция данных в цифрах
  • Агрегатный массив чисел суммированием
  • Python - лучший язык программирования в мире.