PandasSeniorSystem design
Каковы улучшения производительности в Pandas 2.0 (Arrow-backed dtypes, Copy-on-Write)?
Pandas 2.0 добавил Arrow-backed dtypes (меньше памяти, nullable int без float, zero-copy I/O) и Copy-on-Write (CoW), устраняющий SettingWithCopyWarning и делающий поведение срезов детерминированным.
Arrow-backed dtypes в Pandas 2.0
Pandas 2.0 ввёл нативную поддержку Apache Arrow как backend для хранения данных. Столбцы можно создать с Arrow-типом, передав суффикс [pyarrow] в параметр dtype или используя dtype_backend="pyarrow" при чтении файлов.
import pandas as pd
import pyarrow as pa
# Создание DataFrame с Arrow-backed типами
df = pd.DataFrame(
{"id": [1, 2, 3], "name": ["Alice", "Bob", None], "score": [9.5, 8.0, 7.2]},
dtype="ArrowDtype"
)
# Явное указание Arrow-типов
df2 = pd.DataFrame({
"id": pd.array([1, 2, 3], dtype="int32[pyarrow]"),
"name": pd.array(["Alice", "Bob", None], dtype="string[pyarrow]"),
})
# При чтении Parquet/CSV с backend=pyarrow
df3 = pd.read_parquet("data.parquet", dtype_backend="pyarrow")
df4 = pd.read_csv("data.csv", dtype_backend="pyarrow")
print(df2.dtypes)
# id int32[pyarrow]
# name string[pyarrow]
Что даёт Arrow backend
- Nullable integer/boolean без конвертации в float:
int64[pyarrow]хранитNAнативно, а не какNaNв float64. - Меньший расход памяти: Arrow использует буферы с битовыми масками для null-значений вместо sentinel-значений NumPy.
- Ускорение I/O: чтение Parquet через
dtype_backend="pyarrow"даёт zero-copy, когда данные уже в Arrow-формате. - Поддержка вложенных типов:
list[pyarrow],struct[pyarrow],map[pyarrow]— типы, которые NumPy не поддерживает.
Copy-on-Write (CoW)
До Pandas 2.0 изменение среза DataFrame иногда модифицировало оригинал, иногда нет — поведение зависело от того, возвращает ли операция view или копию. Pandas 2.0 вводит Copy-on-Write: любой объект (DataFrame или Series), полученный из другого, считается независимым — данные копируются только в момент первой записи.
import pandas as pd
# Включение CoW (обязательно в pandas 2.x, default в pandas 3.0)
pd.options.mode.copy_on_write = True
df = pd.DataFrame({"a": [1, 2, 3], "b": [4, 5, 6]})
slice_df = df[["a"]] # view, данные не копируются
slice_df["a"] = 99 # здесь происходит копирование (write)
print(df["a"].tolist()) # [1, 2, 3] — оригинал не тронут
print(slice_df["a"].tolist()) # [99, 99, 99]
Практические выгоды CoW
- Устранение
SettingWithCopyWarning— самого частого источника путаницы. - Снижение ненужных копий: Pandas 2.0 откладывает копирование до реального изменения, что уменьшает пиковое потребление памяти в цепочках трансформаций.
- Детерминированное поведение: код работает предсказуемо вне зависимости от того, view или copy возвращает конкретная операция.
Миграция на CoW
# Включить предупреждения о будущих изменениях
pd.options.mode.copy_on_write = "warn" # pandas 2.x
# Найти устаревшие паттерны: chained assignment
df[df["a"] > 1]["b"] = 0 # будет предупреждение
# Правильный вариант
df.loc[df["a"] > 1, "b"] = 0
Подводные камни
- CoW не включён по умолчанию в Pandas 2.x — нужно явно установить
pd.options.mode.copy_on_write = True; в Pandas 3.0 это станет дефолтом. - Arrow backend требует установки pyarrow:
pip install pyarrow, он не входит в базовую зависимость Pandas. - Не все операции поддерживают Arrow-типы: некоторые NumPy-зависимые функции (например,
np.whereнапрямую) могут вернуть NumPy-массив, что приведёт к потере Arrow-типа. - Смешение NumPy и Arrow столбцов в одном DataFrame — законно, но может замедлить операции из-за implicit конвертаций.
- Chained assignment всё ещё опасен без CoW:
df[mask]["col"] = valмолча ничего не делает при CoW — правильно использоватьdf.loc[mask, "col"] = val. - Производительность Arrow неоднородна: Arrow быстрее для string/nested типов и I/O, но для тяжёлых числовых операций NumPy backend может оказаться быстрее из-за оптимизаций BLAS/LAPACK.
- Nullable pd.NA vs float NaN: Arrow-столбцы возвращают
pd.NA, а неnp.nan, что ломает код, проверяющийx != xилиmath.isnan(x). - Сериализация в pickle: Arrow-backed DataFrame сериализуется иначе — не совместим с pickle-файлами, записанными в Pandas 1.x.
Common mistakes
- Объяснять
pandas 2 performanceтолько синтаксисом без shape, dtype, состояния или режима выполнения. - Игнорировать leakage, воспроизводимость, пустые входы и скрытые копии данных.
- Не проверять production-симптомы: latency, память, ретраи, дрейф качества и несовпадение версий.
What the interviewer is testing
- Может ли связать
pandas 2 performanceс реальным контрактом входов и выходов. - Упоминает ли тесты, метрики, reproducibility и диагностику ошибок.
- Видит ли различие между demo-кодом в ноутбуке и production-пайплайном.
- Предлагает ли observability, rollback, ограничения стоимости и стратегию incident replay.