Комментарии (1)
Ответ сгенерирован нейросетью и может содержать ошибки
Структуры данных в Data Science
Введение
Выбор правильной структуры данных — основа эффективного кода. В Data Science работаем как с примитивными структурами Python, так и со специализированными NumPy, Pandas и других библиотек. За 10+ лет выработал понимание, когда какую структуру применять.
Примитивные структуры Python
List (Список)
Упорядоченная, изменяемая коллекция элементов:
data = [1, 2, 3, 4, 5]
data.append(6) # O(1) в среднем
data.pop() # O(1)
data[0] # O(1)
data.insert(0, 0) # O(n)
Когда использовать: небольшие наборы, когда нужен доступ по индексу и изменение размера.
Dictionary (Словарь)
Неупорядоченная (в Python 3.7+ сохраняет порядок) коллекция ключ-значение:
config = {"learning_rate": 0.01, "epochs": 100}
config["batch_size"] = 32 # O(1)
value = config.get("learning_rate") # O(1)
Когда использовать: конфигурации, маппирование, быстрый поиск по ключу.
Set (Множество)
Неупорядоченная коллекция уникальных элементов:
unique_ids = {1, 2, 3, 4, 5}
unique_ids.add(6) # O(1)
if 3 in unique_ids: # O(1)
print("Found")
intersection = {1, 2, 3} & {3, 4, 5} # {3}
Когда использовать: удаление дубликатов, проверка принадлежности, операции с множествами.
Tuple (Кортеж)
Упорядоченная, неизменяемая коллекция:
point = (1, 2)
coords = point[0], point[1] # Распаковка
hash(point) # Можно использовать как ключ
Когда использовать: возвращаемые значения функций, неизменяемые данные, ключи словарей.
NumPy структуры
NumPy Array (ndarray)
Многомерный массив с фиксированным типом данных:
import numpy as np
# 1D array
features = np.array([1.0, 2.5, 3.1])
# 2D array (матрица)
X = np.array([[1, 2, 3], [4, 5, 6]]) # shape: (2, 3)
# 3D array
tensor = np.random.randn(10, 28, 28) # Для изображений
# Операции
result = features * 2 # Векторизация, очень быстро
mean = np.mean(X, axis=0) # По столбцам
std = np.std(X, axis=1) # По строкам
Преимущества:
- Быстрые математические операции (C-реализация)
- Минимальный overhead памяти
- Поддержка векторизации
- Удобные трансляции (broadcasting)
Когда использовать: матричные операции, линейная алгебра, изображения, числовые вычисления.
Pandas структуры
Series
Одномерный индексированный массив данных:
import pandas as pd
temperature = pd.Series(
[20, 21, 22, 21, 20],
index=[Mon, Tue, Wed, Thu, Fri]
)
print(temperature[Mon]) # 20
print(temperature.mean()) # 20.8
DataFrame
Двумерная таблица с именованными колонками и индексом:
df = pd.DataFrame({
id: [1, 2, 3],
name: [Alice, Bob, Charlie],
age: [25, 30, 35],
salary: [50000, 60000, 75000]
})
# Доступ
df[name] # Series
df.loc[0] # Первая строка
df.iloc[0:2] # Первые две строки
# Агрегация
df.groupby(name)[salary].sum()
df[df[age] > 25] # Фильтр
Когда использовать: работа с табличными данными, FE (feature engineering), EDA.
Специализированные структуры
Scipy Sparse Matrix
Для больших матриц с множеством нулей (sparse data):
from scipy.sparse import csr_matrix
# Создание разреженной матрицы
data = [1, 2, 3, 4]
row = [0, 0, 1, 1]
col = [0, 2, 1, 3]
X_sparse = csr_matrix((data, (row, col)), shape=(2, 4))
# Экономия памяти: хранятся только ненулевые элементы
print(X_sparse.memory_usage()) # Намного меньше, чем плотная матрица
Когда использовать: NLP (TF-IDF векторы), текстовые данные, графы, большие разреженные матрицы.
Graph structures (NetworkX)
Для работы с графами и сетями:
import networkx as nx
G = nx.Graph()
G.add_edge(A, B, weight=0.5)
G.add_edge(B, C, weight=0.3)
# Анализ
degrees = dict(G.degree())
shortest_path = nx.shortest_path(G, A, C)
Когда использовать: социальные сети, рекомендательные системы, анализ связей.
Деревья данных
Tree structures
Для иерархических данных:
class TreeNode:
def __init__(self, value):
self.value = value
self.children = []
def add_child(self, child):
self.children.append(child)
# Decision Trees (используются в sklearn)
from sklearn.tree import DecisionTreeRegressor
dt = DecisionTreeRegressor(max_depth=5)
dt.fit(X_train, y_train)
Когда использовать: иерархические данные, decision trees, категориальные признаки.
Сравнение производительности
import timeit
# List vs NumPy
py_list = list(range(1000000))
np_array = np.array(py_list)
# List: медленнее
time_list = timeit.timeit(lambda: [x*2 for x in py_list[:1000]], number=10000)
# NumPy: быстрее в 10-100 раз
time_np = timeit.timeit(lambda: np_array[:1000] * 2, number=10000)
Практические рекомендации
Выбор структуры:
- Числовые вычисления → NumPy array
- Табличные данные → Pandas DataFrame
- Разреженные данные → Scipy sparse matrix
- Конфигурация/маппирование → Dict
- Быстрая проверка наличия → Set
- Граф отношений → NetworkX Graph
- Иерархия → Tree structure
Оптимизация памяти:
- Уменьшай dtype (int32 вместо int64, float32 вместо float64)
- Используй категориальные типы в Pandas
- Применяй sparse matrices для разреженных данных
Оптимизация скорости:
- Векторизуй операции (NumPy вместо циклов)
- Используй Pandas vectorized методы (.apply() как последний вариант)
- Профилируй код (cProfile, line_profiler)
Заключение
Выбор правильной структуры данных — залог производительности и масштабируемости. Каждая структура имеет свою временную сложность и область применения. Глубокое понимание этих различий — критически важно для опытного Data Scientist.