Python для инженера данных и Основы NumPy
Цели лекции
- Переключить мышление с императивного (циклы
for) на векторное (операции над массивами). - Освоить Pythonic style: писать код, который работает быстрее и читается легче (List Comprehensions, Slicing).
- Понять физику работы 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.
Пример: У нас есть данные о продажах (матрица 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 и понижайте разрядность, если это возможно, чтобы не упасть по памяти.