Каковы преимущества NumPy перед обычными списками Python?

StackOverflow https://stackoverflow.com/questions/993984

Вопрос

В чем преимущества NumPy над обычными списками Python?

У меня есть около 100 серий финансовых рынков, и я собираюсь создать массив кубов размером 100x100x100 = 1 миллион ячеек.Я буду регрессировать (с тремя переменными) каждый x по каждому y и z, чтобы заполнить массив стандартными ошибками.

Я слышал, что для «больших матриц» мне следует использовать NumPy, а не списки Python, из соображений производительности и масштабируемости.Дело в том, что я знаю списки Python, и они, похоже, мне подходят.

Какие преимущества я получу, если перейду на NumPy?

Что, если бы у меня было 1000 серий (то есть 1 миллиард ячеек с плавающей запятой в кубе)?

Это было полезно?

Решение

Массивы NumPy более компактны, чем списки Python - список списков, как вы описываете, в Python займет не менее 20 МБ или около того, а 3D-массив NumPy с числами с плавающей запятой одинарной точности уместится в 4 МБ.Доступ к элементам чтения и записи также ускоряется с помощью NumPy.

Возможно, вас не так уж волнует миллион ячеек, но вас определенно волнует миллиард ячеек - ни один из подходов не подходит для 32-битной архитектуры, но с 64-битными сборками NumPy сойдет с рук 4 ГБ или около того. , одному Python потребуется как минимум около 12 ГБ (множество указателей, размер которых удваивается) — гораздо более дорогостоящее оборудование!

Разница в основном связана с «косвенностью»: список Python представляет собой массив указателей на объекты Python, не менее 4 байтов на указатель плюс 16 байтов даже для самого маленького объекта Python (4 для указателя типа, 4 для счетчика ссылок, 4 для значения - и распределители памяти округляют до 16).Массив NumPy представляет собой массив однородных значений: числа одинарной точности занимают 4 байта каждое, числа двойной точности — 8 байтов.Менее гибкий, но за гибкость стандартных списков Python приходится платить значительную сумму!

Другие советы

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

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

x = numpy.fromfile(file=open("data"), dtype=float).reshape((100, 100, 100))

Сумма по второму измерению:

s = x.sum(axis=1)

Найдите ячейки, которые находятся выше порога:

(x > 0.5).nonzero()

Удалите каждый срез с четным индексом по третьему измерению:

x[:, :, ::2]

Также с массивами NumPy работает множество полезных библиотек.Например, библиотеки статистического анализа и визуализации.

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

Алекс упомянул эффективность памяти, а Роберто упомянул удобство, и это оба хорошие моменты.Еще несколько идей, я упомяну скорость и функциональность.

Функциональность:Вы получаете множество встроенных функций: NumPy, FFT, свертки, быстрый поиск, базовую статистику, линейную алгебру, гистограммы и т. д.И действительно, кто может жить без БПФ?

Скорость:Вот тест на суммирование по списку и массиву NumPy, показывающий, что сумма в массиве NumPy выполняется в 10 раз быстрее (в этом тесте результат может варьироваться).

from numpy import arange
from timeit import Timer

Nelements = 10000
Ntimeits = 10000

x = arange(Nelements)
y = range(Nelements)

t_numpy = Timer("x.sum()", "from __main__ import x")
t_list = Timer("sum(y)", "from __main__ import y")
print("numpy: %.3e" % (t_numpy.timeit(Ntimeits)/Ntimeits,))
print("list:  %.3e" % (t_list.timeit(Ntimeits)/Ntimeits,))

что в моих системах (пока я выполняю резервное копирование) дает:

numpy: 3.004e-05
list:  5.363e-04

Вот хороший ответ из FAQ на сайт scipy.org:

Какие преимущества имеют массивы NumPy по сравнению с (вложенными) списками Python?

Списки Python — это эффективные контейнеры общего назначения.Они поддерживают (справедливо) эффективную вставку, удаление, добавление и конкатенацию, а понимание списка Python позволяет им легко строить и манипулировать.Однако у них есть определенные ограничения:Они не поддерживают «векторизованные» операции, такие как элемент, добавление и умножение, и тот факт, что они могут содержать объекты различных типов, означает, что Python должен хранить информацию типа для каждого элемента и должен выполнять код отправки типа при работе на каждом элементе.Это также означает, что очень немногие операции списка могут быть выполнены с помощью эффективных петлей C - каждая итерация потребует проверки типа и другой бухгалтерии Python API.

Все они выделили почти все основные различия между массивом numpy и списком Python, я просто кратко изложу их здесь:

  1. Массивы Numpy имеют фиксированный размер при создании, в отличие от списков Python (которые могут динамически расти).Изменение размера ndarray приведет к созданию нового массива и удалению оригинала.

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

  3. Массивы Numpy облегчают математические и другие типы операций с большими объемами данных.Обычно такие операции выполняются более эффективно и с меньшим количеством кода, чем это возможно при использовании последовательностей Python.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top