Как работает pd.read_csv() и какие параметры помогают с производительностью (chunksize, dtype, usecols)?
pd.read_csv() читает CSV в DataFrame; для больших файлов используйте usecols (нужные столбцы), dtype (экономия памяти), chunksize (итерация по частям) и engine='pyarrow' для скорости.
pd.read_csv(): параметры производительности
pd.read_csv() — основной способ загрузки табличных данных в Pandas. По умолчанию он читает весь файл целиком, автоматически определяет типы и возвращает DataFrame. На больших файлах это медленно и расточительно по памяти.
usecols — читать только нужные столбцы
Pandas всё равно парсит весь файл построчно, но не держит ненужные столбцы в памяти. Экономия памяти пропорциональна числу отброшенных столбцов.
import pandas as pd
df = pd.read_csv(
"large_dataset.csv",
usecols=["id", "amount", "created_at"],
)
dtype — задать типы явно
Автодетект типов — самая затратная часть парсинга. Pandas читает несколько тысяч строк для оценки типа. Явное задание ускоряет загрузку и снижает расход памяти.
df = pd.read_csv(
"orders.csv",
dtype={
"id": "int32",
"amount": "float32",
"status": "category", # строки с малым числом уникальных значений
"country": "category",
},
parse_dates=["created_at"],
)
print(df.dtypes)
print(df.memory_usage(deep=True).sum() / 1e6, "MB")
Тип category для строк с ограниченным числом уникальных значений даёт 5–10x экономию памяти по сравнению с object.
chunksize — итерация по частям
Возвращает TextFileReader — итератор чанков. Каждый чанк — обычный DataFrame. Позволяет обрабатывать файлы, не помещающиеся в RAM.
results = []
chunk_iter = pd.read_csv(
"huge_log.csv",
chunksize=100_000,
usecols=["user_id", "event", "ts"],
dtype={"user_id": "int32", "event": "category"},
)
for chunk in chunk_iter:
agg = chunk.groupby("event")["user_id"].nunique()
results.append(agg)
final = pd.concat(results).groupby(level=0).sum()
print(final)
engine и дополнительные параметры
engine="pyarrow"— в Pandas 2.0+ значительно быстрее стандартного C-движка на больших файлах.engine="c"— дефолт, стабилен.low_memory=False— отключает смешанный-тип inference (полезно, если столбец содержит числа и строки).nrows=N— читать только первые N строк для разведочного анализа.skiprows/skipfooter— пропуск строк в начале/конце.na_values— дополнительные строки, считаемые NaN.
# Быстрый профиль памяти до и после оптимизации
df_slow = pd.read_csv("orders.csv")
print("Before:", df_slow.memory_usage(deep=True).sum() / 1e6, "MB")
df_fast = pd.read_csv(
"orders.csv",
usecols=["id", "amount", "status"],
dtype={"id": "int32", "amount": "float32", "status": "category"},
engine="pyarrow",
)
print("After:", df_fast.memory_usage(deep=True).sum() / 1e6, "MB")
Подводные камни
- Неверный
dtypeдля столбца с NaN:int32не поддерживает NaN — используйтеInt32(nullable integer) илиfloat32. parse_dates=Trueпарсит индекс, а не все столбцы; для столбцов нужен список имён.chunksizeвозвращает итератор, а не DataFrame — нельзя сразу вызвать.shape.engine="pyarrow"не поддерживает все параметры (например,skipfooter).low_memory=True(дефолт) может даватьDtypeWarningдля смешанных столбцов — лечится явнымdtype.- Кодировка файла: без явного
encoding="utf-8"на Windows может применяться cp1252, ломая кириллицу. categoryтип требует осторожности при конкатенации чанков с разными наборами категорий.
Common mistakes
- Объяснять
read csv performanceтолько синтаксисом без shape, dtype, состояния или режима выполнения. - Игнорировать leakage, воспроизводимость, пустые входы и скрытые копии данных.
- Не проверять production-симптомы: latency, память, ретраи, дрейф качества и несовпадение версий.
What the interviewer is testing
- Может ли связать
read csv performanceс реальным контрактом входов и выходов. - Упоминает ли тесты, метрики, reproducibility и диагностику ошибок.
- Видит ли различие между demo-кодом в ноутбуке и production-пайплайном.