Работа с CSV файлами на Python: от основ до продвинутых техник

Раздел: Python -> Файловый ввод-вывод

Основные способы работы с CSV в Python

Наиболее эффективное решение для работы с CSV в Python - использование встроенного модуля csv. Этот модуль предоставляет классы reader и writer, которые корректно обрабатывают различные диалекты CSV, кавычки и экранирование.

import csv

# Чтение файла
with open('data.csv', 'r', encoding='utf-8') as f:
    reader = csv.reader(f)
    for row in reader:
        print(row)

# Запись файла
with open('output.csv', 'w', newline='', encoding='utf-8') as f:
    writer = csv.writer(f)
    writer.writerow(['Имя', 'Возраст', 'Город'])
    writer.writerow(['Анна', 25, 'Москва'])
    writer.writerow(['Петр', 30, 'Санкт-Петербург'])

ввод программ на python (ввод данных в программе python)

['Имя', 'Возраст', 'Город']
['Анна', '25', 'Москва']
['Петр', '30', 'Санкт-Петербург']

Python file io (ввод-вывод файлов в python)

В примере чтения все строки преобразуются в списки строк. При записи параметр newline='' предотвращает добавление лишних пустых строк в Windows.

Типичные проблемы:

  • Разделитель отличен от запятой - используйте параметр delimiter=';'.
  • Файл в другой кодировке - укажите корректный параметр encoding (например, 'cp1251').
  • Пустые строки в конце файла - модуль csv сам их пропускает при чтении, но при записи флаг newline='' важен.

Как прочитать CSV файл с помощью csv.DictReader?

DictReader представляет каждую строку в виде словаря, где ключи - имена столбцов из первой строки (заголовка). Это удобно для доступа к полям по имени.

import csv

with open('data.csv', 'r', encoding='utf-8') as f:
    reader = csv.DictReader(f)
    for row in reader:
        print(row['Имя'], row['Возраст'])

Python temp files (временные файлы в python)

Анна 25
Петр 30

Python index files (индексация файлов в python)

Частая ошибка:

  • Файл без заголовков - DictReader не сможет определить имена полей, все строки будут читаться как данные. В таком случае можно передать параметр fieldnames явно.
  • Пробелы в заголовках (например, "Имя " с пробелом) - dict будет содержать ключ с пробелом. Рекомендуется предварительно обрабатывать строки заголовков.

Как записать CSV файл с помощью DictWriter?

DictWriter упрощает запись, когда данные представлены в виде словарей. Позволяет указать порядок столбцов.

import csv

fieldnames = ['Имя', 'Возраст', 'Город']
rows = [
    {'Имя': 'Анна', 'Возраст': 25, 'Город': 'Москва'},
    {'Имя': 'Петр', 'Возраст': 30, 'Город': 'Санкт-Петербург'}
]

with open('output.csv', 'w', newline='', encoding='utf-8') as f:
    writer = csv.DictWriter(f, fieldnames=fieldnames)
    writer.writeheader()
    writer.writerows(rows)

File python class (класс для работы с файлами в python)

Имя,Возраст,Город
Анна,25,Москва
Петр,30,Санкт-Петербург

Python file utf 8 (кодировка utf-8 для файлов в python)

Проблемы:

  • Если в словаре отсутствует ключ, соответствующий fieldnames, возникнет ошибка ValueError. Чтобы пропускать отсутствующие поля, используется параметр restval.

Как обработать CSV с нестандартным разделителем (например, табуляция)?

Укажите параметр delimiter в объекте reader или writer.

import csv

with open('data.tsv', 'r', encoding='utf-8') as f:
    reader = csv.reader(f, delimiter='\t')
    for row in reader:
        print(row)

Python config files (конфигурационные файлы в python)

['Имя', 'Возраст', 'Город']
['Анна', '25', 'Москва']
['Петр', '30', 'Санкт-Петербург']

Python copy file (копирование файла в python)

Ошибки:

  • Игнорирование параметра quoting - если внутри данных встречаются кавычки, может потребоваться настройка csv.QUOTE_MINIMAL и других.

Как читать большие CSV файлы по частям?

Используйте генераторный подход или модуль pandas с параметром chunksize.

import csv

def read_csv_chunks(file_path, chunk_size=1000):
    with open(file_path, 'r', encoding='utf-8') as f:
        reader = csv.reader(f)
        chunk = []
        for i, row in enumerate(reader):
            chunk.append(row)
            if (i + 1) % chunk_size == 0:
                yield chunk
                chunk = []
        if chunk:
            yield chunk

for chunk in read_csv_chunks('large.csv', 500):
    process(chunk)

Python log file (логирование в файл в python)

Предостережение:

  • При таком подходе заголовок тоже попадает в чанк, если не обработать первую строку отдельно.

Как работать с CSV с помощью библиотеки pandas?

Pandas предоставляет функцию read_csv с широкими возможностями автоматического определения типов, обработки пропусков и именования столбцов.

import pandas as pd

df = pd.read_csv('data.csv', encoding='utf-8')
print(df.head())
print(df.dtypes)

# Фильтрация, преобразование
df_filtered = df[df['Возраст'] > 28]
df_filtered.to_csv('filtered.csv', index=False)

Python file methods (методы работы с файлами в python)

    Имя  Возраст              Город
0   Анна      25             Москва
1   Петр      30  Санкт-Петербург

Имя       object
Возраст    int64
Город     object

File models in python (модели файлов в python)

Нюансы:

  • При больших файлах pandas может потреблять много памяти. Используйте chunksize или dtype для оптимизации.
  • Проблемы с разделителем решаются параметром sep, с кодировкой - encoding.

Как использовать numpy для числовых CSV?

Если файл содержит только числа, удобно применить numpy.loadtxt или numpy.genfromtxt.

import numpy as np

data = np.loadtxt('numbers.csv', delimiter=',', skiprows=1)
print(data.mean(axis=0))

# Или с пропущенными значениями
data2 = np.genfromtxt('messy.csv', delimiter=',', missing_values='N/A', filling_values=0.0)

File handle python (обработка файлов в python)

[25.5 30. ]

Ограничения:

  • Не подходит для смешанных типов данных без дополнительной обработки.
  • Ошибки при несоответствии числа столбцов в строках.
- Python line find (поиск строки в файле python)
- Python csv file (работа с csv файлами в python)
- Python работа с данными файла (работа с данными из файла в python)

Расширенные примеры работы с CSV

Пример 1. Чтение CSV с кастомным диалектом и обработка кавычек

Иногда файлы используют нестандартные правила экранирования. Модуль csv позволяет создавать собственный диалект.

Пример
import csv

csv.register_dialect('mydialect',
                     delimiter='|',
                     quotechar='"',
                     doublequote=True,
                     skipinitialspace=True,
                     lineterminator='\n',
                     quoting=csv.QUOTE_MINIMAL)

with open('custom.csv', 'r', encoding='utf-8') as f:
    reader = csv.reader(f, dialect='mydialect')
    for row in reader:
        print(row)
['Имя', 'Возраст', 'Город']
['Анна', '25', 'Москва']

Пример 2. Объединение нескольких CSV файлов

Сценарий, когда нужно объединить файлы с одинаковой структурой. Используется модуль csv или pandas.

Пример
import csv
import glob

header_written = False
with open('merged.csv', 'w', newline='', encoding='utf-8') as out:
    writer = csv.writer(out)
    for filename in glob.glob('data_*.csv'):
        with open(filename, 'r', encoding='utf-8') as f:
            reader = csv.reader(f)
            header = next(reader)
            if not header_written:
                writer.writerow(header)
                header_written = True
            for row in reader:
                writer.writerow(row)
(merged.csv содержит все строки из data_1.csv, data_2.csv, ...)

Пример 3. Преобразование типов данных при чтении

Модуль csv читает всё как строки. Для численных преобразований можно применить map или pandas.

Пример
import csv

with open('data.csv', 'r', encoding='utf-8') as f:
    reader = csv.reader(f)
    header = next(reader)
    rows = []
    for row in reader:
        name = row[0]
        age = int(row[1]) if row[1].isdigit() else None
        city = row[2]
        rows.append((name, age, city))
print(rows)
[('Анна', 25, 'Москва'), ('Петр', 30, 'Санкт-Петербург')]

Пример 4. Обработка CSV с пропущенными значениями в pandas

Pandas автоматически распознаёт NaN. Можно задать список значений, которые считать пропущенными.

Пример
import pandas as pd

df = pd.read_csv('missing.csv', na_values=['NA', 'N/A', ''])
print(df.isnull().sum())
df_filled = df.fillna({'Возраст': df['Возраст'].median(), 'Город': 'Неизвестно'})
df_filled.to_csv('filled.csv', index=False)
Имя       0
Возраст   2
Город     1

Пример 5. Запись CSV с использованием разных форматов кавычек

Параметр quoting определяет, когда ставить кавычки: csv.QUOTE_ALL - оборачивать все поля, csv.QUOTE_NONNUMERIC - только нечисловые.

Пример
import csv

rows = [['Анна', 25, 'Москва'], ['Петр', 30, 'Санкт-Петербург']]
with open('quoted.csv', 'w', newline='', encoding='utf-8') as f:
    writer = csv.writer(f, quoting=csv.QUOTE_ALL)
    writer.writerows(rows)
"Анна","25","Москва"
"Петр","30","Санкт-Петербург"

Пример 6. Сортировка строк CSV по столбцу без загрузки всего файла в память

Для больших файлов можно использовать внешнюю сортировку или модуль csv с временными файлами. Ниже упрощённый вариант с pandas в режиме chunksize.

Пример
import pandas as pd

chunks = pd.read_csv('large.csv', chunksize=10000, encoding='utf-8')
sorted_chunks = [chunk.sort_values('Возраст') for chunk in chunks]
sorted_df = pd.concat(sorted_chunks).sort_values('Возраст')
sorted_df.to_csv('sorted.csv', index=False)
(файл sorted.csv содержит строки, упорядоченные по возрастанию возраста)

Пример 7. Использование csv.Sniffer для автоматического определения диалекта

Если формат CSV неизвестен, можно применить csv.Sniffer, который анализирует образец текста.

Пример
import csv

with open('unknown.csv', 'r', encoding='utf-8') as f:
    sample = f.read(1024)
    dialect = csv.Sniffer().sniff(sample)
    f.seek(0)
    reader = csv.reader(f, dialect)
    for row in reader:
        print(row)
['Имя', 'Возраст', 'Город']
['Анна', '25', 'Москва']

Пример 8. Обработка CSV с BOM (Byte Order Mark)

Файлы из Windows (Excel) часто начинаются с BOM (\ufeff). Его можно удалить или указать кодировку utf-8-sig.

Пример
import csv

with open('excel.csv', 'r', encoding='utf-8-sig') as f:
    reader = csv.reader(f)
    for row in reader:
        print(row)
['Имя', 'Возраст', 'Город']
['Анна', '25', 'Москва']

Если игнорировать BOM, первая строка будет содержать символ '\ufeff' в начале первого поля.

Работа с CSV файлами в Python - comments

En
Python csv file (python)