machine-learningЛекцияPython

Python для инженера данных и Основы NumPy

👀 Загрузка...

Цели лекции

  1. Переключить мышление с императивного (циклы for) на векторное (операции над массивами).
  2. Освоить Pythonic style: писать код, который работает быстрее и читается легче (List Comprehensions, Slicing).
  3. Понять физику работы NumPy: почему он быстрее чистого Python и что такое Broadcasting.

Часть 1: Python Refresher — Пишем как PRO

Здесь мы не учим синтаксис с нуля. Мы разбираем инструменты, критически важные для обработки данных.

1.1. List Comprehensions (Списковые включения)

Это способ создания новых списков на основе существующих в одну строку.

  • Зачем это инженеру: Это быстрее обычного цикла for (оптимизировано на уровне байт-кода) и компактнее.
  • Синтаксис: [expression for item in list if conditional]
# Вместо создания пустого списка и добавления квадратов чисел в цикле, мы пишем:
squares = [x**2 for x in range(10) if x % 2 == 0]

1.2. Lambda-функции

Анонимные функции-однострочники.

  • Где применяются: Чаще всего внутри методов .map(), .filter() или при сортировке сложных структур. В Pandas (на следующей неделе) это будет наш основной инструмент для трансформации колонок.
  • Суть: Если функция нужна один раз и занимает одну строку — не давайте ей имя (def), используйте lambda.

1.3. Slicing (Срезы)

Умение "вырезать" куски данных.

  • Формула: sequence[start:stop:step]

Важные нюансы срезов

stop не включается в выборку. Инженерный трюк: [::-1] разворачивает последовательность за O(N).


Часть 2: NumPy — Фундамент Data Science

NumPy (Numerical Python) — это библиотека, на которой стоит весь современный ML (Pandas, Scikit-Learn, TensorFlow — все они под капотом используют NumPy).

2.1. Аналогия: Список vs Массив

Чтобы понять, почему NumPy быстрый, представим склад.

Это "разношерстный" склад. В одной коробке лежат гвозди, в другой — слон, в третьей — текст. Чтобы пройтись по складу, грузчик должен заглянуть в каждую коробку, проверить тип содержимого и решить, что с ним делать. Это долго (Overhead).

Итог: NumPy массивы хранятся в непрерывной области памяти (как в C/C++), что позволяет процессору использовать кэширование и векторизацию.

2.2. Векторизация (Vectorization)

Это отказ от явных циклов Python в пользу операций над массивами целиком.

Главное правило Data Scientist'a

Если вы пишете цикл for для обработки числовых данных в Python — вы почти наверняка делаете что-то не так. Используйте методы NumPy.

  • Концепция: Вместо того чтобы складывать элементы двух массивов по одному в цикле for, мы даем команду "Сложи массив А и массив Б".
  • SIMD (Single Instruction, Multiple Data): На низком уровне процессор выполняет одну инструкцию сразу над множеством данных.

Часть 3: Магия Broadcasting (Транслирование)

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

3.1. Как это работает (Аналогия)

Представьте, что вы хотите умножить матрицу (таблицу чисел) на 2.

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

3.2. Правила Broadcasting

Два массива совместимы, если:

  1. Их размерности равны.
  2. Или одна из размерностей равна 1.

Пример: У нас есть данные о продажах (матрица 3x4: 3 магазина, 4 товара). Мы хотим вычесть средние продажи по каждому товару (вектор длины 4). NumPy поймет, что вектор (1x4) нужно "растянуть" на 3 строки вниз, и вычтет его из каждой строки матрицы.


Часть 4: Индексация и Типы данных

4.1. Fancy Indexing (Продвинутая индексация)

Мы можем передавать в качестве индекса не просто число, а другой массив или список.

Boolean Masking: Самый мощный инструмент фильтрации.

data = np.array([1, 2, 3, 4, 5])
mask = data > 3  # [False, False, False, True, True]
filtered = data[mask] # [4, 5]

Мы не пишем if, мы накладываем "маску".

4.2. Типы данных имеют значение

В Python int безразмерен (может быть сколь угодно большим). В NumPy вы должны мыслить как инженер:

  • int8: от -128 до 127. Экономит память в 8 раз по сравнению с int64.
  • float32: Стандарт для нейросетей (достаточная точность, в 2 раза меньше памяти, чем float64).

OOM (Out Of Memory)

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


🧠 Проверка знаний

Почему NumPy обрабатывает данные быстрее, чем стандартные списки (list) в Python?

Какое условие необходимо для того, чтобы два массива NumPy разных размеров были совместимы для операции Broadcasting (Транслирование)?