Перейти к содержимому
Теория · NumPy и pandas · урок 1 из 12

Массивы NumPy

Данные для машинного обучения (machine learning) — это таблицы из тысяч чисел. Список Python может их хранить, но считать по нему приходится в цикле, по одному элементу:

Python
import numpy as np

prices = [120, 95, 300, 210]
with_tax = []
for p in prices:
    with_tax.append(p * 1.2)
print(with_tax)  # [144.0, 114.0, 360.0, 252.0]

a = np.array(prices)
print(a * 1.2)  # [144. 114. 360. 252.]

Библиотека numpy хранит числа в массиве (array) и выполняет арифметику сразу над всеми элементами. Функция np.array превращает список в массив, а выражение a * 1.2 умножает каждый элемент без цикла. Такую запись называют векторизацией (vectorization). Она короче цикла, а на тысячах строк работает в десятки раз быстрее.

Форма и тип

У массива есть атрибут shape — кортеж длин по каждому измерению. Массив a одномерный, его форма (4,).

Таблица задаётся списком строк и становится двумерным массивом. Форма (3, 2) значит три строки и два столбца. Для такого массива len(X) возвращает число строк, то есть X.shape[0].

Python
X = np.array([[1.5, 20.0], [2.0, 35.0], [0.5, 12.0]])
print(X.shape)  # (3, 2)
print(X.dtype)  # float64
print(np.array([1, 2.5]).dtype)  # float64
print(a / 2)  # [ 60.   47.5 150.  105. ]

Атрибут dtype — тип элементов (data type), один на весь массив. Дробные числа хранятся как float64. Если в списке смешаны целые и дробные числа, numpy приводит все элементы к дробному типу.

Массив из одних целых чисел получает целый тип, но деление a / 2 всё равно даёт дробные числа. Общий тип и делает арифметику быстрой: numpy не проверяет каждый элемент отдельно, как это приходится делать циклу Python.

Сумма и среднее

Функции np.sum и np.mean считают сумму и среднее элементов. У среднего есть и метод: a.mean() даёт то же число. Арифметика между массивом и числом применяется к каждому элементу, поэтому отклонения от среднего записываются одной строкой:

Python
print(np.sum(a), np.mean(a), a.mean())  # 725 181.25 181.25
print(a - a.mean())  # [-61.25 -86.25 118.75  28.75]
print(np.array([1, 2, 3]) + np.array([10, 20, 30]))  # [11 22 33]

Два массива одной формы складываются поэлементно: первый элемент с первым, второй со вторым.

Частая ошибка

Арифметику применили к списку, а не к массиву:

Python
doubled = prices * 2  # ✗
print(doubled)  # [120, 95, 300, 210, 120, 95, 300, 210]

Python не сообщает об ошибке. Умножение списка на целое число повторяет список, а сложение двух списков склеивает их. Умножение списка на дробное число вызывает TypeError. Превратите список в массив вызовом np.array(prices), и тогда * 2 удвоит каждое число.

Подпишись, чтобы пройти курс

Курс бесплатный. Войди через Telegram и подпишись на канал — откроются все уроки.

Войти другим способом