Урок курса
Загрузка CSV с явными типами и датами через read_csv
NumPy и pandas: практический тренажёрВ прошлом уроке DataFrame создавался вручную — из словаря или списка словарей. В реальной работе данные почти всегда приходят из файла, и самый распространённый формат — CSV. Здесь разберём, как pd.read_csv превращает текстовый файл в DataFrame за один вызов.
pd.read_csv: чтение CSV по пути и файловому объекту
Базовый вызов выглядит так:
import pandas as pd
df = pd.read_csv('data/orders.csv')
Первый аргумент filepath_or_buffer — это либо строка с путём к файлу, либо файловый объект. Pandas принимает оба варианта одинаково.
Путь может быть относительным или абсолютным:
# относительный путь
df = pd.read_csv('data/orders.csv')
# абсолютный путь
df = pd.read_csv('/home/user/projects/data/orders.csv')
Вместо пути можно передать любой файловый объект — например, открытый через open() или созданный через io.StringIO (полезно в тестах и при работе с данными из памяти):
import io
csv_text = """id,date,amount,category
1,2024-01-15,99.5,food
2,2024-02-20,150.0,tech
"""
buf = io.StringIO(csv_text)
df = pd.read_csv(buf)
print(df)
В обоих случаях pandas делает одно и то же: читает первую строку файла как заголовок столбцов, а дальше — строки данных.
Типы pandas выводит автоматически, просматривая значения каждого столбца. Числа без дробной части становятся int64, числа с точкой — float64, всё остальное — object (строки). Посмотреть, что получилось:
print(df.dtypes)
# id int64
# date object
# amount float64
# category object
Здесь date — это строка (object), потому что pandas по умолчанию не пытается распознавать даты. Автовывод типов работает хорошо для числовых столбцов, но для дат и столбцов с особыми требованиями к типу нужны явные параметры — они будут следующим шагом.
Выбор нужных столбцов через usecols
Когда CSV-файл содержит десятки столбцов, а нужны только три — нет смысла загружать всё. Параметр usecols позволяет указать именно те столбцы, которые должны попасть в DataFrame.
Передавать можно список имён:
import pandas as pd
df = pd.read_csv('data/orders.csv', usecols=['id', 'date', 'amount'])
print(df.columns.tolist())
# ['id', 'date', 'amount']
Если имена столбцов в файле заранее неизвестны или нужно обратиться к ним по позиции, usecols принимает и список целых чисел:
# Взять первый, второй и третий столбцы (0-based)
df = pd.read_csv('data/orders.csv', usecols=[0, 1, 2])
Оба варианта дают одинаковый результат, если позиции соответствуют тем же столбцам.
Один момент, который сбивает с толку: порядок столбцов в результирующем DataFrame определяется не списком usecols, а порядком в самом файле. То есть если написать usecols=['amount', 'id', 'date'], в DataFrame они всё равно окажутся в том порядке, в котором идут в CSV — id, date, amount.
Практический смысл usecols не только в удобстве, но и в экономии памяти: pandas не читает и не хранит данные из пропущенных столбцов вообще. Для больших файлов с широкими таблицами это ощутимо.
Явные типы и разбор дат: параметры dtype и parse_dates
Автоматический вывод типов, который pandas делает при чтении CSV, работает предсказуемо для чисел, но часто ошибается в деталях: столбец с целыми числами получает int64, хотя для экономии памяти лучше подошёл бы int32; столбец с ценами может стать object, если в нём встречается запятая вместо точки. Чтобы не исправлять это постфактум через astype, нужные типы задаются прямо при чтении через параметр dtype.
Параметр dtype
dtype принимает словарь, где ключ — имя столбца, значение — нужный тип:
import pandas as pd
df = pd.read_csv(
'data/orders.csv',
dtype={
'id': 'int32',
'amount': 'float64',
'category': 'str'
}
)
В качестве типов работают строки NumPy/pandas ('int32', 'float64', 'Int64' с заглавной I для nullable-целых) и Python-типы (str, float). Pandas применяет преобразование во время чтения, поэтому никаких отдельных вызовов astype после загрузки не нужно.
Если в файле окажется значение, которое нельзя привести к указанному типу, pandas бросит ValueError — и это хорошо: ошибка сразу сигнализирует о грязных данных, а не прячется в неожиданном NaN где-то внутри DataFrame.
Один нюанс: столбцы, которые не указаны в словаре dtype, получают тип автоматически, как обычно. Словарь не обязан покрывать все столбцы.
Параметр parse_dates
Даты — отдельная история. Даже если в файле написано 2024-01-15, pandas по умолчанию читает это как строку (object). Чтобы столбец стал datetime64[ns] прямо при загрузке, используется parse_dates:
df = pd.read_csv(
'data/orders.csv',
parse_dates=['date']
)
parse_dates принимает список имён столбцов (или позиций). Pandas пытается распознать формат автоматически — ISO-8601 (YYYY-MM-DD) он обрабатывает без проблем. Для нестандартных форматов вроде 15/01/2024 автораспознавание может не сработать, и тогда потребуется дополнительный шаг уже после загрузки. Но для большинства реальных датасетов, где дата записана в стандартном виде, parse_dates закрывает задачу полностью.
Оба параметра прекрасно работают вместе:
df = pd.read_csv(
'data/orders.csv',
dtype={'id': 'int32', 'amount': 'float64'},
parse_dates=['date']
)
Такой вызов даёт id типа int32, amount типа float64, date типа datetime64[ns] — всё в один шаг, без постобработки. Как убедиться, что типы действительно применились корректно, разберём в следующей секции.
Проверка типов через df.dtypes и сквозной пример
После того как read_csv отработал с нужными параметрами, остаётся один вопрос: применились ли они так, как ожидалось? Ответ даёт df.dtypes.
df.dtypes возвращает Series, где индекс — имена столбцов, а значения — их типы. Смотреть его нужно сразу после загрузки, до любой дальнейшей обработки — именно тогда он подтверждает, что параметры dtype и parse_dates сработали корректно.
Разберём на конкретном примере. Возьмём CSV с четырьмя столбцами: id, date, amount, category. Нужны только первые три, id должен быть int32, amount — float64, а date — datetime64:
import pandas as pd
import io
csv_text = '''id,date,amount,category
1,2024-01-15,99.5,food
2,2024-02-20,150.0,tech
3,2024-03-10,45.25,food
'''
buf = io.StringIO(csv_text)
df = pd.read_csv(
buf,
usecols=['id', 'date', 'amount'],
dtype={'id': 'int32', 'amount': 'float64'},
parse_dates=['date']
)
print(df.dtypes)
Вывод:
id int32
date datetime64[ns]
amount float64
dtype: object
Это именно то, что задавалось при вызове. category в DataFrame вообще нет — usecols его исключил. id получил int32, а не дефолтный int64. date стал datetime64[ns], а не строкой. amount — float64.
Если какой-то тип не совпал с ожидаемым, чаще всего причина в одном из двух:
- Неизвестный ключ в
dtype— pandas молча игнорирует его, столбец получает автоматический тип. Например, если написатьdtype={'amout': 'float64'}(опечатка), ошибки не будет, ноamountокажетсяfloat64лишь случайно (по автовыводу), а намерение останется незамеченным. Проверяйтеdf.dtypesименно поэтому. - Несуществующий столбец в
parse_dates— поведение противоположное: pandas броситValueError.
Это значит, что имя столбца в parse_dates не совпадает ни с одним столбцом в файле (или он был исключён через usecols). Здесь ошибка видна сразу.
Во всех случаях df.dtypes помогает локализовать проблему: если тип столбца не тот, что ожидался, — ищите опечатку в ключе dtype или проверьте, не исключён ли нужный столбец через usecols.
df.dtypes — тот же атрибут, что уже использовался при ручном создании DataFrame в предыдущем уроке. Разница только в контексте: там он описывал структуру, которую задавали явно через словарь; здесь — подтверждает, что read_csv правильно интерпретировал CSV-файл. Этот же datetime64[ns]-столбец позже станет базой для работы с компонентами дат через .dt — но это уже отдельная тема.
Закрепите тему на задачах
После загрузки проверьте число строк, dtype и значение ключа с ведущими нулями. Разделитель и кодировка могут создать правдоподобную, но неверную таблицу.
Загрузка CSV с явными типами и датами через read_csv — задача по NumPy и pandas
pandas read_csv: usecols, dtype и parse_dates в задаче
pandas read_csv: конфликт usecols и parse_dates
Откройте условие и решите задачу перед чтением следующей темы. В задачах на код проверяется программа, в тестовых заданиях — выбранный ответ. Для последовательного обучения вернитесь в программу бесплатного курса.
Задача 1
DataFrame загружен командой:
df = pd.read_csv(buf, usecols=['a', 'b'], dtype={'a': 'int32'}, parse_dates=['b'])
Какой dtype будет у столбца 'b' в выводе df.dtypes, если 'b' содержит значения вида '2024-01-15'?
Задача 2
CSV-файл содержит столбцы: id, name, price, date. Выполняется вызов:
df = pd.read_csv(path, usecols=['id', 'price'])
Сколько столбцов будет в df и какие именно?
Задача 3
Вы хотите загрузить CSV из переменной path, выбрать только столбцы 'user_id' и 'created_at', задать для 'user_id' тип int32 и распарсить 'created_at' как datetime — всё в одном вызове. Какой вызов pd.read_csv правильно решает эту задачу?
Задача 4
Найди и исправь: три ошибки в вызове pd.read_csv с usecols, dtype и parse_dates
Что уже дано
Проверяющая система выполняет скрытый start_code, который создаёт файл transactions.csv в рабочей директории. Содержимое файла:
txn_id,user_id,amount,currency,txn_date 1,42,100.0,RUB,2024-01-05 2,17,250.5,USD,2024-01-12 3,42,75.0,RUB,2024-02-01 4,99,500.0,EUR,2024-02-14
В редакторе уже есть сломанный код. В нём ровно три ошибки в трёх независимых строках:
- В
usecolsуказан столбец'currency', хотя по условию он должен быть исключён — нужны только'txn_id','user_id','amount','txn_date'. - В словаре
dtypeключ для идентификатора транзакции написан как'txn_id', но тип указан'float64'— хотя это целочисленный идентификатор и должен быть'int32'. - В
parse_datesуказан столбец'amount'— хотя разбирать как дату нужно столбец'txn_date'.
Каждая ошибка находится в отдельной строке. Исправьте все три.
Что нужно сделать
Отредактируйте код так, чтобы после исправления переменная df содержала DataFrame со следующими свойствами:
df.shapeравен(4, 4);- столбцы —
['txn_id', 'user_id', 'amount', 'txn_date'](без'currency'); df['txn_id'].dtype—int32;df['user_id'].dtype—int32;df['amount'].dtype—float64;df['txn_date'].dtype—datetime64[ns].
Ввод и вывод
stdin не используется. Печатать через print в stdout ничего не нужно.
Проверяющая система читает верхнеуровневую переменную df после выполнения вашего кода и проверяет её shape, столбцы и dtypes.
Без регистрации. Гостевая проверка не сохраняет прогресс. Для сохранения перейдите к уроку.
Отправьте решение, чтобы увидеть результаты тестов.
Задача 5
pd.read_csv с usecols, dtype и parse_dates: загрузка и проверка dtypes
Что уже дано
Проверяющая система выполняет скрытый start_code, который создаёт файл employees.csv в рабочей директории. Содержимое файла:
emp_id,name,salary,department,hired_on 1,Алина,75000.0,Разработка,2021-03-15 2,Борис,92000.0,Аналитика,2019-11-01 3,Вера,64000.0,Разработка,2022-06-30 4,Глеб,110000.0,Управление,2018-04-12 5,Дина,81000.0,Аналитика,2020-09-07
Файл создаётся до выполнения вашего кода. Никаких заранее созданных переменных нет — вы читаете файл сами.
Что нужно сделать
Напишите верхнеуровневый код (без функций), который:
- Загружает файл
employees.csvчерезpd.read_csvс тремя параметрами:
usecols=['emp_id', 'salary', 'hired_on']— загрузить только эти три столбца;dtype={'emp_id': 'int32', 'salary': 'float64'}— задать типы явно;parse_dates=['hired_on']— разобрать столбецhired_onкак дату.
- Сохраняет результат в переменную
df. - Создаёт переменную
col_names— список имён столбцов:list(df.columns). - Создаёт переменную
emp_id_dtype— строковое представление dtype столбцаemp_id:str(df['emp_id'].dtype). - Создаёт переменную
hired_on_kind— первый символ dtype столбцаhired_on:df['hired_on'].dtype.kind. Дляdatetime64[ns]это'M'.
Проверяющая система читает переменные df, col_names, emp_id_dtype и hired_on_kind после выполнения вашего кода.
Ввод и вывод
stdin не используется. Печатать через print в stdout ничего не нужно.
Проверяющая система читает верхнеуровневые переменные df, col_names, emp_id_dtype и hired_on_kind после выполнения вашего кода и проверяет:
df.shapeравен(5, 3);col_namesсодержит ровно['emp_id', 'salary', 'hired_on'];emp_id_dtypeравен'int32';hired_on_kindравен'M'(datetime);- столбец
nameи столбецdepartmentвdfотсутствуют.
Без регистрации. Гостевая проверка не сохраняет прогресс. Для сохранения перейдите к уроку.
Отправьте решение, чтобы увидеть результаты тестов.
Задача 6
pd.read_csv через файловый объект: usecols, dtype, parse_dates и вывод dtypes
Что уже дано
Скрытый start_code создаёт файл orders.csv в рабочей директории. Содержимое файла:
order_id,customer,amount,status,order_date 101,Алина,1500.0,shipped,2024-02-10 102,Борис,320.5,pending,2024-03-22 103,Вера,870.0,shipped,2024-04-05 104,Глеб,45.0,cancelled,2024-04-18
Файл создаётся до выполнения вашего кода. Никаких заранее созданных переменных нет — вы открываете файл и читаете его сами.
Что нужно сделать
Напишите верхнеуровневый код (без функций), который:
- Открывает файл
orders.csvчерезopen('orders.csv', encoding='utf-8')и передаёт файловый объект вpd.read_csvвместо строки-пути. - Вызывает
pd.read_csvс тремя параметрами:
usecols=['order_id', 'amount', 'order_date']— загрузить только эти три столбца;dtype={'order_id': 'int32', 'amount': 'float64'}— задать типы явно;parse_dates=['order_date']— разобрать столбецorder_dateкак дату.
- Сохраняет результат в переменную
df. - Создаёт переменную
dtypes_dict— словарь вида{имя_столбца: str(dtype)}для всех столбцовdf. Пример построения:{col: str(df[col].dtype) for col in df.columns}. - Создаёт переменную
row_count— целое число строк вdf(df.shape[0]).
Проверяющая система читает переменные df, dtypes_dict и row_count после выполнения вашего кода.
Ввод и вывод
stdin не используется. Печатать через print в stdout ничего не нужно.
Проверяющая система читает верхнеуровневые переменные df, dtypes_dict и row_count после выполнения вашего кода и проверяет:
df.shapeравен(4, 3);- столбцы
df— ровно['order_id', 'amount', 'order_date'](безcustomerиstatus); dtypes_dict['order_id']равен'int32';dtypes_dict['amount']равен'float64';dtypes_dict['order_date']начинается с'datetime64';row_countравен4.
Без регистрации. Гостевая проверка не сохраняет прогресс. Для сохранения перейдите к уроку.
Отправьте решение, чтобы увидеть результаты тестов.
Задача 7
pd.read_csv через io.StringIO: конфликт usecols и parse_dates
Что уже дано
Проверяющая система выполняет скрытый start_code, который не создаёт никаких переменных. Все данные вы формируете сами.
Что нужно сделать
Напишите верхнеуровневый код (без функций), который:
- Создаёт CSV-источник в памяти через
io.StringIOсо следующим содержимым:
visit_id,page,duration,visit_date 1,home,30,2024-04-01 2,catalog,120,2024-04-03 3,home,15,2024-04-07 4,checkout,200,2024-04-10
- Загружает данные через
pd.read_csvс тремя параметрами:
usecols=['visit_id', 'duration', 'visit_date']— загрузить только эти три столбца (безpage);dtype={'visit_id': 'int32', 'duration': 'int32'}— задать типы явно;parse_dates=['visit_date']— разобрать столбецvisit_dateкак дату.
- Сохраняет результат в переменную
df. - Создаёт переменную
shape— кортежdf.shape. - Создаёт переменную
cols— список имён столбцов:list(df.columns). - Создаёт переменную
dtypes_dict— словарь{имя_столбца: str(df[имя_столбца].dtype) for имя_столбца in df.columns}.
Проверяющая система читает переменные df, shape, cols и dtypes_dict после выполнения вашего кода.
Ввод и вывод
stdin не используется. Печатать через print в stdout ничего не нужно.
Проверяющая система читает верхнеуровневые переменные df, shape, cols и dtypes_dict после выполнения вашего кода и проверяет:
shapeравен(4, 3);colsсодержит ровно['visit_id', 'duration', 'visit_date'](безpage);dtypes_dict['visit_id']равен'int32';dtypes_dict['duration']равен'int32';dtypes_dict['visit_date']начинается с'datetime64';- столбец
pageвdfотсутствует.
Без регистрации. Гостевая проверка не сохраняет прогресс. Для сохранения перейдите к уроку.
Отправьте решение, чтобы увидеть результаты тестов.
Задачи к уроку
- Загрузка CSV с явными типами и датами через readcsv — задача по NumPy и pandas
dtypes, если 'b' содержит значения вида '2024-01-15'? Проверьте ответ в задаче из бесплатного курса NumPy и pandas.
- Загрузка CSV в pandas: dtype, usecols и разбор дат
Как загрузить CSV с нужными типами и датами в pandas? Пример чтения файла с выбором столбцов и упражнение с проверкой кода.
- pandas readcsv: конфликт usecols и parsedates
Найдите причину ошибки загрузки CSV через pandas.readcsv, когда usecols и parsedates указывают несовместимые столбцы.
Продолжить с сохранением прогресса
Перейдите к уроку в учебном кабинете.
