Рубрики
Без рубрики

Высокопроизводительные математические парадигмы в Python

Изучите лучшие методы оценки любого математического выражения в огромном наборе данных.

Автор оригинала: Harshit Tyagi.

Сравнение производительности различных парадигм реализации в python

Для любой дисциплины, требующей больших объемов данных, одним из основных накладных расходов является ускорение научных и численных вычислений. С критически важным для производительности приложением и конвейером обработки данных возникает необходимость в оптимальной реализации парадигмы и выборе правильного набора библиотек. После работы над научными(метаболомика) и финансовыми проектами я решил собрать эти советы и рекомендации, которые я разработал и изучил.

Мотивация всего этого поста-это строка, которую мой наставник в Прояснить попросил меня усвоить и применить на практике:

Существует разница между написанием кода на python и написанием питонического кода.

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

Функции, определяющие математические выражения

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

Допустим, существует математическое выражение, которое должно быть вычислено по массиву из 100 000 чисел: y = ⎷|sin(x) + cos(x)|

Создание списка чисел с помощью функции диапазона,

n = 1000000
data_num = range(n)

Давайте рассмотрим разнообразие реализаций и сравним все это в конце, используя библиотеку timeit:

  1. Очень простой и понятный подход заключается в циклическом переборе всего набора данных и добавлении выходных данных функции f(x)(определенной выше)к объекту списка выходных данных.
otpt = []
for x in data_list: 
    otpt.append(f(x))
  1. Мы можем использовать итераторы:
return [f(x) for x in data_list]
  1. То же самое можно сделать с помощью метода eval() python:
exp = 'abs(cos(x) + sin(x)) ** 0.5'  
return [eval(exp) for x in data_list]
  1. Мы можем реализовать тот же алгоритм, используя тактику векторизации numpy.
import numpy as np
data_np = np.arange(1000000) 
def f4(data_np):  
    """using the numpy vectorization 
    """
    return (np.abs(np.cos(data_np) + sin(data_np)) ** 0.5)
  1. Другой библиотекой, которая специализируется на оценке таких числовых выражений, является numexpr. Причина, по которой эта библиотека оказывается очень удобной, заключается в встроенной поддержке многопоточности.
import numexpr as ne
ex = 'abs(cos(a) + sin(a)) ** 0.5'
ne.set_num_threads(5) 
return ne.evaluate(ex)

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

Запись выходных данных каждой функции в виде tpt1, tpt2 и так далее и тому подобное.

Мы можем использовать метод numpy allclose() для проверки двух объектов ndarray.

np.allclose(otpt1, otpt2)
np.allclose(otpt1, otpt3)
np.allclose(otpt1, otpt4)
np.allclose(otpt1, otpt5)

Все они должны вернуться к истине, чтобы мы могли взглянуть на самый важный вопрос, который является фокусом этого блога:

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

После передачи необходимых аргументов в приведенную выше функцию, которая использует время, которое она повторяет, чтобы оценить время и отсортировать наблюдаемые значения.

function_list = ['f1', 'f2', 'f3', 'f4', 'f5']
data_com_list = ['data_num', 'data_num', 'data_num', 'data_np', 'data_np']
record_comp_time(function_list, data_com_list)

Мы получаем следующие скорости производительности.

Как видно из результатов сравнения, функция, использующая numexpr , выдает результат в рекордно короткие сроки, за которым следует функция 4, которая является функцией, использующей библиотеку numpy.

Вот ссылка на мой репозиторий GitHub для всей базы кода:

коды харшита/python_paradigms __A руководство по: Как сравнить различные парадигмы реализации в python? – коды харшита/python_paradigms_github.com

Вывод

Для каждой операции, требующей больших объемов данных, у python есть несколько способов повысить производительность вашего кода. Учитывая проблему, над оптимальностью можно работать, используя правильную комбинацию различных парадигм и выбор библиотек. Помимо парадигм, есть несколько очень полезных библиотек, которые улучшают скорость выполнения кода python.

Точно так же, как numexpr имеет большой спектр операций, которые делают численную оценку более плавной и быстрой, есть

  • Cython который объединяет легкость написания python со скоростью C.
  • Numba ,- он динамически компилирует код python для процессора.
  • Встроенный модуль Python многопроцессорная обработка для параллельной обработки

И считать…

В следующих постах я поделюсь некоторыми советами и рекомендациями по операциям ввода-вывода с использованием панд, параллельных вычислений и компиляции.

Оставайтесь с нами для получения дополнительной информации…