Как читать CSV файлы в Python: методы, примеры, подводные камни
CSV (Comma-Separated Values) - популярный формат для хранения табличных данных. В Python существует несколько способов чтения таких файлов. Ниже рассмотрены ключевые подходы с примерами кода, пояснениями и разбором типичных проблем.
Базовое чтение с помощью модуля csv
Как прочитать CSV файл построчно, обрабатывая каждую строку как список?
Модуль csv в стандартной библиотеке Python предоставляет класс reader. Он автоматически разбирает строки по разделителю (по умолчанию запятая) и корректно обрабатывает кавычки и экранирование.
import csv
# Файл data.csv:
# name,age,city
# Alice,30,New York
# Bob,25,London
with open('data.csv', newline='', encoding='utf-8') as f:
reader = csv.reader(f)
for row in reader:
print(row)
Python работа с csv (работа с csv-файлами в python)
['name', 'age', 'city'] ['Alice', '30', 'New York'] ['Bob', '25', 'London']
Csv формат python (формат csv в python)
Первая строка часто содержит заголовки. Их можно пропустить вызовом next(reader) или использовать DictReader (см. варианты).
Типичные ошибки и их решение:
- UnicodeDecodeError - возникает при неверной кодировке. Решение: указать правильную кодировку, например encoding='cp1251' для русской Windows.
- Пустые строки в выводе - если в файле есть символы возврата каретки. Решение: добавить параметр newline='' при открытии файла.
- Неправильный разделитель - файл использует точку с запятой вместо запятой. Решение: указать delimiter=';'.
Вариант 1: DictReader - чтение с заголовками
Как получить доступ к значениям по именам столбцов, а не по индексам?
csv.DictReader использует первую строку как ключи словаря. Каждая строка возвращается в виде OrderedDict (или обычного словаря в новых версиях).
import csv
with open('data.csv', newline='', encoding='utf-8') as f:
reader = csv.DictReader(f)
for row in reader:
print(row['name'], row['age'])
Python читаем csv (чтение csv-файла в python)
Alice 30 Bob 25
Python создать csv (создание csv-файла в python)
Параметр fieldnames позволяет задать свои заголовки, если их нет в файле.
Проблема: разные кавычки в CSV
Если в файле используются нестандартные кавычки, можно задать quotechar (по умолчанию '"').
Вариант 2: Pandas - для анализа данных
Как быстро загрузить CSV в DataFrame для дальнейшей обработки?
Библиотека pandas предоставляет функцию read_csv() с множеством параметров: выбор столбцов, типы данных, обработка пропусков и т. д.
import pandas as pd
df = pd.read_csv('data.csv')
print(df.head())
name age city
0 Alice 30 New York
1 Bob 25 London
Pandas автоматически распознает заголовки и типы данных. Для файлов с разделителем табуляции используется sep='\t'.
Распространённая ошибка: пропущенные значения
По умолчанию пустые ячейки становятся NaN. Можно указать keep_default_na=False или свои маркеры через na_values.
Вариант 3: NumPy - для числовых данных
Как загрузить CSV только с числами в массив NumPy?
Функция numpy.genfromtxt() или loadtxt() подходят для однородных числовых таблиц.
import numpy as np
data = np.genfromtxt('numbers.csv', delimiter=',', skip_header=1)
print(data)
[[ 1. 2. 3.] [ 4. 5. 6.]]
Параметр dtype задаёт тип данных, missing_values обрабатывает пропуски.
Ошибка: нечисловые значения
Если в столбце есть текст, genfromtxt преобразует его в NaN. Для сложной смешанной загрузки лучше использовать pandas.
Вариант 4: Ручной разбор строки
Что делать, если CSV имеет нестандартный формат, который не обрабатывается модулем csv?
Можно считать файл обычным текстом и разбить строки с помощью str.split(). Но такой подход ломается при наличии кавычек или запятых внутри полей.
with open('simple.csv', 'r') as f:
for line in f:
parts = line.strip().split(',')
print(parts)
['name', 'age', 'city'] ['Alice', '30', 'New York']
Этот вариант подходит только для гарантированно простых данных без экранирования.
Ошибка: разделение внутри кавычек
Если поле содержит запятую (например, "New York, NY"), простой split разобьёт его некорректно. Рекомендуется всегда использовать модуль csv.
Расширенные примеры чтения CSV в Python
1. Чтение большого CSV частями (chunking) с csv.reader
Как обработать CSV, который не помещается в оперативную память?
Модуль csv позволяет читать файл построчно. Для пакетной обработки можно использовать итератор и счётчик строк.
import csv
CHUNK_SIZE = 1000
with open('huge.csv', newline='', encoding='utf-8') as f:
reader = csv.reader(f)
chunk = []
for i, row in enumerate(reader):
if i == 0: # заголовок
continue
chunk.append(row)
if (i % CHUNK_SIZE) == 0:
# обработка chunk (например, запись в БД)
print(f"Обработано строк: {i}")
chunk = []
if chunk:
print(f"Обработано строк: {i}")
Обработано строк: 1000 Обработано строк: 2000 ...
2. Чтение CSV с разными разделителями и кавычками
Как загрузить TSV (табуляция) или файл с нестандартными кавычками?
import csv
# TSV с обрамлением полей одинарными кавычками
with open('data.tsv', newline='', encoding='utf-8') as f:
reader = csv.reader(f, delimiter='\t', quotechar="'")
for row in reader:
print(row)
['name', 'age', 'city'] ['Alice', '30', 'New York']
3. Использование pandas для обработки кодировок и пропусков
Как корректно загрузить CSV в кодировке Windows-1251 с пропущенными значениями, обозначенными символом '---'?
import pandas as pd
df = pd.read_csv('russian_data.csv',
encoding='cp1251',
sep=';',
na_values=['---', 'N/A', ''])
print(df.isnull().sum())
name 0 age 2 city 1 dtype: int64
4. Чтение CSV с помощью numpy и преобразование типов
Как загрузить CSV столбцы с разными типами (int, float, str) в структурированный массив?
import numpy as np
data = np.genfromtxt('mixed.csv',
delimiter=',',
names=True,
dtype=None,
encoding='utf-8')
print(data['age']) # возраст как int
print(data['name']) # имя как bytes (строка в байтах)
[30 25] [b'Alice' b'Bob']
Для получения строк удобно использовать dtype='U10' или после загрузки применить .astype(str).
5. Обработка ошибок при чтении: пропуск битых строк
Что делать, если в CSV есть строки с неверным количеством полей?
import csv
with open('dirty.csv', newline='', encoding='utf-8') as f:
reader = csv.reader(f)
for row_num, row in enumerate(reader, 1):
try:
# ожидаем 3 поля
if len(row) != 3:
raise ValueError(f"Неверное число полей: {len(row)}")
# обработка row
except ValueError as e:
print(f"Пропущена строка {row_num}: {e}")
Пропущена строка 5: Неверное число полей: 2
6. Чтение CSV из строки (StringIO)
Как прочитать CSV данные, которые не хранятся в файле, а передаются как строка?
import csv
from io import StringIO
data = """name,age
Alice,30
Bob,25
"""
with StringIO(data) as f:
reader = csv.DictReader(f)
for row in reader:
print(row)
{'name': 'Alice', 'age': '30'}
{'name': 'Bob', 'age': '25'}
7. Чтение CSV с произвольным именами столбцов (без заголовков)
Как прочитать CSV без заголовочной строки, присвоив свои имена столбцам?
import csv
with open('no_header.csv', newline='', encoding='utf-8') as f:
reader = csv.reader(f)
for row in reader:
print(row)
['Alice', '30'] ['Bob', '25']
А если нужны заголовки, можно использовать DictReader с параметром fieldnames:
import csv
fieldnames = ['name', 'age']
with open('no_header.csv', newline='', encoding='utf-8') as f:
reader = csv.DictReader(f, fieldnames=fieldnames)
for row in reader:
print(row)
{'name': 'Alice', 'age': '30'}
{'name': 'Bob', 'age': '25'}