Чтение и запись файлов CSV на Python

Чтение и запись файлов CSV на Python

Посмотрим правде в глаза: вам нужно получать информацию в свои программы и из них с помощью не только клавиатуры и консоли. Обмен информацией через текстовые файлы является распространенным способом обмена информацией между программами. Одним из самых популярных форматов обмена данными является формат CSV. Но как ты это используешь?

Давайте проясним одно: вам не нужно (и не нужно) создавать собственный анализатор CSV с нуля. Есть несколько вполне приемлемых библиотек, которые вы можете использовать. Pythoncsv library будет работать в большинстве случаев. Если ваша работа требует большого количества данных или численного анализа,pandas library также имеет возможности синтаксического анализа CSV, который должен обработать все остальное.

В этой статье вы узнаете, как читать, обрабатывать и анализировать CSV из текстовых файлов с использованием Python. Вы увидите, как работают файлы CSV, изучите важнейшую библиотекуcsv, встроенную в Python, и увидите, как работает синтаксический анализ CSV с использованием библиотекиpandas.

Итак, начнем!

__ Take the Quiz: Проверьте свои знания с помощью интерактивного теста «Чтение и запись файлов CSV на Python». По окончании вы получите оценку, чтобы вы могли отслеживать прогресс в обучении с течением времени:

Что такое файл CSV?

Файл CSV (файл с разделенными запятыми значениями) представляет собой тип простого текстового файла, который использует специальную структуру для упорядочения табличных данных. Поскольку это обычный текстовый файл, он может содержать только фактические текстовые данные, другими словами, печатаемые символыASCII илиUnicode.

Структура CSV-файла определяется его именем. Обычно файлы CSV используют запятую для разделения каждого конкретного значения данных. Вот как выглядит эта структура:

column 1 name,column 2 name, column 3 name
first row data 1,first row data 2,first row data 3
second row data 1,second row data 2,second row data 3
...

Обратите внимание, что каждый фрагмент данных разделен запятой. Обычно первая строка идентифицирует каждый фрагмент данных, другими словами, имя столбца данных. Каждая последующая строка после этого является фактическими данными и ограничена только ограничениями размера файла.

Как правило, символ разделителя называется разделителем, и запятая используется не единственно. Другие популярные разделители включают символы табуляции ( ), двоеточия (:) и точки с запятой (;). Правильный анализ файла CSV требует, чтобы мы знали, какой разделитель используется.

Откуда берутся файлы CSV?

Файлы CSV обычно создаются программами, которые обрабатывают большие объемы данных. Это удобный способ экспортировать данные из электронных таблиц и баз данных, а также импортировать или использовать их в других программах. Например, вы можете экспортировать результаты программы интеллектуального анализа данных в файл CSV, а затем импортировать их в электронную таблицу для анализа данных, создания графиков для презентации или подготовки отчета для публикации.

С файлами CSV очень легко работать программно. Любой язык, который поддерживает ввод текстовых файлов и манипуляции со строками (например, Python), может работать с файлами CSV напрямую.

Разбор файлов CSV с помощью встроенной библиотеки Python CSV

csv library обеспечивает функциональность как для чтения, так и для записи в файлы CSV. Разработанный для работы с CSV-файлами, созданными в Excel, он легко адаптируется для работы с различными форматами CSV. Библиотекаcsv содержит объекты и другой код для чтения, записи и обработки данных из файлов CSV и в них.

Чтение файлов CSV сcsv

Чтение из файла CSV осуществляется с помощью объектаreader. CSV-файл открывается как текстовый файл с помощью встроенной функции Pythonopen(), которая возвращает файловый объект. Затем это передаетсяreader, который выполняет тяжелую работу.

Вот файлemployee_birthday.txt:

name,department,birthday month
John Smith,Accounting,November
Erica Meyers,IT,March

Вот код, чтобы прочитать это:

import csv

with open('employee_birthday.txt') as csv_file:
    csv_reader = csv.reader(csv_file, delimiter=',')
    line_count = 0
    for row in csv_reader:
        if line_count == 0:
            print(f'Column names are {", ".join(row)}')
            line_count += 1
        else:
            print(f'\t{row[0]} works in the {row[1]} department, and was born in {row[2]}.')
            line_count += 1
    print(f'Processed {line_count} lines.')

Это приводит к следующему выводу:

Column names are name, department, birthday month
    John Smith works in the Accounting department, and was born in November.
    Erica Meyers works in the IT department, and was born in March.
Processed 3 lines.

Каждая строка, возвращаемаяreader, представляет собой список элементовString, содержащих данные, найденные путем удаления разделителей. Первая возвращаемая строка содержит имена столбцов, которые обрабатываются особым образом.

Чтение файлов CSV в словарь с помощьюcsv

Вместо того, чтобы иметь дело со списком отдельных элементовString, вы также можете читать данные CSV непосредственно в словарь (техническиOrdered Dictionary).

Опять же, наш входной файлemployee_birthday.txt выглядит следующим образом:

name,department,birthday month
John Smith,Accounting,November
Erica Meyers,IT,March

Вот код для чтения в качестве словаря на этот раз:

import csv

with open('employee_birthday.txt', mode='r') as csv_file:
    csv_reader = csv.DictReader(csv_file)
    line_count = 0
    for row in csv_reader:
        if line_count == 0:
            print(f'Column names are {", ".join(row)}')
            line_count += 1
        print(f'\t{row["name"]} works in the {row["department"]} department, and was born in {row["birthday month"]}.')
        line_count += 1
    print(f'Processed {line_count} lines.')

Это приводит к тому же выводу, что и раньше:

Column names are name, department, birthday month
    John Smith works in the Accounting department, and was born in November.
    Erica Meyers works in the IT department, and was born in March.
Processed 3 lines.

Откуда взялись ключи словаря? Предполагается, что первая строка CSV-файла содержит ключи, используемые для построения словаря. Если у вас их нет в CSV-файле, вы должны указать свои собственные ключи, установив необязательный параметрfieldnames для списка, содержащего их.

Дополнительные параметры Python CSVreader

Объектreader может обрабатывать различные стили файлов CSV, указавadditional parameters, некоторые из которых показаны ниже:

  • delimiter указывает символ, используемый для разделения каждого поля. По умолчанию используется запятая (',').

  • quotechar указывает символ, используемый для окружения полей, содержащих символ-разделитель. По умолчанию используется двойная кавычка (' " ').

  • escapechar определяет символ, используемый для экранирования символа-разделителя, если кавычки не используются. По умолчанию это не escape-символ.

Эти параметры заслуживают дополнительного пояснения. Предположим, вы работаете со следующим файломemployee_addresses.txt:

name,address,date joined
john smith,1132 Anywhere Lane Hoboken NJ, 07030,Jan 4
erica meyers,1234 Smith Lane Hoboken NJ, 07030,March 2

Этот CSV-файл содержит три поля:name,address иdate joined, разделенных запятыми. Проблема в том, что данные для поляaddress также содержат запятую, обозначающую почтовый индекс.

Есть три различных способа справиться с этой ситуацией:

  • Use a different delimiter
    Таким образом, запятую можно безопасно использовать в самих данных. Вы используете необязательный параметрdelimiter, чтобы указать новый разделитель.

  • Wrap the data in quotes
    Особый характер выбранного вами разделителя игнорируется в строках в кавычках. Следовательно, вы можете указать символ, используемый для цитирования, с помощью необязательного параметраquotechar. Пока этот символ также не отображается в данных, все в порядке.

  • Escape the delimiter characters in the data
    Escape-символы работают так же, как и в строках формата, сводя на нет интерпретацию экранируемого символа (в данном случае - разделителя). Если используется escape-символ, его необходимо указать с помощью необязательного параметраescapechar.

Запись файлов CSV сcsv

Вы также можете записать в файл CSV, используя объектwriter и метод.write_row():

import csv

with open('employee_file.csv', mode='w') as employee_file:
    employee_writer = csv.writer(employee_file, delimiter=',', quotechar='"', quoting=csv.QUOTE_MINIMAL)

    employee_writer.writerow(['John Smith', 'Accounting', 'November'])
    employee_writer.writerow(['Erica Meyers', 'IT', 'March'])

Необязательный параметрquotechar сообщаетwriter, какой символ использовать для цитирования полей при записи. Однако использование кавычек определяется необязательным параметромquoting:

  • Если дляquoting установлено значениеcsv.QUOTE_MINIMAL, то.writerow() будет указывать поля, только если они содержатdelimiter илиquotechar. Это случай по умолчанию.

  • Если дляquoting установлено значениеcsv.QUOTE_ALL, то.writerow() процитирует все поля.

  • Если дляquoting установлено значениеcsv.QUOTE_NONNUMERIC, то.writerow() будет заключать в кавычки все поля, содержащие текстовые данные, и преобразует все числовые поля в тип данныхfloat.

  • Если дляquoting задано значениеcsv.QUOTE_NONE, тогда.writerow() будет избегать разделителей вместо их заключения в кавычки. В этом случае вы также должны указать значение для необязательного параметраescapechar.

Чтение файла в виде простого текста показывает, что файл создается следующим образом:

John Smith,Accounting,November
Erica Meyers,IT,March

Запись файла CSV из словаря с помощьюcsv

Поскольку вы можете считывать наши данные в словарь, это будет справедливо, если вы сможете записать их и из словаря:

import csv

with open('employee_file2.csv', mode='w') as csv_file:
    fieldnames = ['emp_name', 'dept', 'birth_month']
    writer = csv.DictWriter(csv_file, fieldnames=fieldnames)

    writer.writeheader()
    writer.writerow({'emp_name': 'John Smith', 'dept': 'Accounting', 'birth_month': 'November'})
    writer.writerow({'emp_name': 'Erica Meyers', 'dept': 'IT', 'birth_month': 'March'})

В отличие отDictReader, параметрfieldnames требуется при записи словаря. Если подумать, это имеет смысл: без спискаfieldnamesDictWriter не может знать, какие ключи использовать для извлечения значений из ваших словарей. Он также использует ключи вfieldnames для записи первой строки в качестве имен столбцов.

Код выше генерирует следующий выходной файл:

emp_name,dept,birth_month
John Smith,Accounting,November
Erica Meyers,IT,March

Анализ файлов CSV с помощью библиотекиpandas

Конечно, библиотека Python CSV - не единственная игра в городе. Чтение файлов CSV также возможно вpandas. Настоятельно рекомендуется, если у вас есть много данных для анализа.

pandas - это библиотека Python с открытым исходным кодом, которая предоставляет высокопроизводительные инструменты анализа данных и простые в использовании структуры данных. pandas доступен для всех установок Python, но он является ключевой частью дистрибутиваAnaconda и очень хорошо работает вJupyter notebooks для обмена данными, кодом, результатами анализа, визуализациями и описательным текстом. .

Установитьpandas и его зависимости вAnaconda легко:

$ conda install pandas

Как иpip/pipenv для других установок Python:

$ pip install pandas

Мы не будем вдаваться в подробности того, как работаетpandas или как его использовать. Чтобы подробнее узнать об использованииpandas для чтения и анализа больших наборов данных, ознакомьтесь с превосходной статьейShantnu Tiwari’s оworking with large Excel files in pandas.

Чтение файлов CSV сpandas

Чтобы продемонстрировать некоторые возможности CSV-файлаpandas, я создал несколько более сложный для чтения файл под названиемhrdata.csv. Содержит данные о сотрудниках компании:

Name,Hire Date,Salary,Sick Days remaining
Graham Chapman,03/15/14,50000.00,10
John Cleese,06/01/15,65000.00,8
Eric Idle,05/12/14,45000.00,10
Terry Jones,11/01/13,70000.00,3
Terry Gilliam,08/12/14,48000.00,7
Michael Palin,05/23/13,66000.00,8

Чтение CSV вpandasDataFrame выполняется быстро и просто:

import pandas
df = pandas.read_csv('hrdata.csv')
print(df)

Вот и все: три строки кода, и только одна из них выполняет реальную работу. pandas.read_csv() открывает, анализирует и считывает предоставленный CSV-файл и сохраняет данные вDataFrame. ПечатьDataFrame дает следующий результат:

             Name Hire Date   Salary  Sick Days remaining
0  Graham Chapman  03/15/14  50000.0                   10
1     John Cleese  06/01/15  65000.0                    8
2       Eric Idle  05/12/14  45000.0                   10
3     Terry Jones  11/01/13  70000.0                    3
4   Terry Gilliam  08/12/14  48000.0                    7
5   Michael Palin  05/23/13  66000.0                    8

Вот несколько моментов, на которые стоит обратить внимание:

  • Во-первых,pandas распознал, что первая строка CSV содержит имена столбцов, и использовал их автоматически. Я называю это Добротой.

  • Однакоpandas также использует целочисленные индексы с отсчетом от нуля вDataFrame. Это потому, что мы не сказали, каким должен быть наш индекс.

  • Кроме того, если вы посмотрите на типы данных наших столбцов, вы увидите, чтоpandas правильно преобразовал столбцыSalary иSick Days remaining в числа, но столбецHire Date является все ещеString. Это легко подтверждается в интерактивном режиме:

    >>>

>>> print(type(df['Hire Date'][0]))

Давайте решать эти проблемы по одному. Чтобы использовать другой столбец в качестве индексаDataFrame, добавьте необязательный параметрindex_col:

import pandas
df = pandas.read_csv('hrdata.csv', index_col='Name')
print(df)

Теперь полеName - это наш индексDataFrame:

               Hire Date   Salary  Sick Days remaining
Name
Graham Chapman  03/15/14  50000.0                   10
John Cleese     06/01/15  65000.0                    8
Eric Idle       05/12/14  45000.0                   10
Terry Jones     11/01/13  70000.0                    3
Terry Gilliam   08/12/14  48000.0                    7
Michael Palin   05/23/13  66000.0                    8

Затем давайте исправим тип данных поляHire Date. Вы можете заставитьpandas читать данные как дату с помощью необязательного параметраparse_dates, который определяется как список имен столбцов, которые обрабатываются как даты:

import pandas
df = pandas.read_csv('hrdata.csv', index_col='Name', parse_dates=['Hire Date'])
print(df)

Обратите внимание на разницу в выходных данных:

                Hire Date   Salary  Sick Days remaining
Name
Graham Chapman 2014-03-15  50000.0                   10
John Cleese    2015-06-01  65000.0                    8
Eric Idle      2014-05-12  45000.0                   10
Terry Jones    2013-11-01  70000.0                    3
Terry Gilliam  2014-08-12  48000.0                    7
Michael Palin  2013-05-23  66000.0                    8

Дата теперь правильно отформатирована, что легко подтверждается в интерактивном режиме:

>>>

>>> print(type(df['Hire Date'][0]))

Если в ваших файлах CSV нет имен столбцов в первой строке, вы можете использовать необязательный параметрnames, чтобы указать список имен столбцов. Вы также можете использовать это, если хотите переопределить имена столбцов, указанные в первой строке. В этом случае вы также должны указатьpandas.read_csv() игнорировать существующие имена столбцов, используя необязательный параметрheader=0:

import pandas
df = pandas.read_csv('hrdata.csv',
            index_col='Employee',
            parse_dates=['Hired'],
            header=0,
            names=['Employee', 'Hired','Salary', 'Sick Days'])
print(df)

Обратите внимание, что, поскольку имена столбцов изменились, столбцы, указанные в дополнительных параметрахindex_col иparse_dates, также должны быть изменены. Теперь это приводит к следующему выводу:

                    Hired   Salary  Sick Days
Employee
Graham Chapman 2014-03-15  50000.0         10
John Cleese    2015-06-01  65000.0          8
Eric Idle      2014-05-12  45000.0         10
Terry Jones    2013-11-01  70000.0          3
Terry Gilliam  2014-08-12  48000.0          7
Michael Palin  2013-05-23  66000.0          8

Запись файлов CSV сpandas

Конечно, если вы снова не можете получить данные изpandas, это не принесет вам много пользы. ЗаписатьDataFrame в файл CSV так же просто, как прочитать его. Давайте запишем данные с новыми именами столбцов в новый файл CSV:

import pandas
df = pandas.read_csv('hrdata.csv',
            index_col='Employee',
            parse_dates=['Hired'],
            header=0,
            names=['Employee', 'Hired', 'Salary', 'Sick Days'])
df.to_csv('hrdata_modified.csv')

Единственное различие между этим кодом и приведенным выше кодом чтения заключается в том, что вызовprint(df) был заменен наdf.to_csv(), предоставляя имя файла. Новый CSV-файл выглядит следующим образом:

Employee,Hired,Salary,Sick Days
Graham Chapman,2014-03-15,50000.0,10
John Cleese,2015-06-01,65000.0,8
Eric Idle,2014-05-12,45000.0,10
Terry Jones,2013-11-01,70000.0,3
Terry Gilliam,2014-08-12,48000.0,7
Michael Palin,2013-05-23,66000.0,8

Заключение

Если вы понимаете основы чтения CSV-файлов, вы никогда не будете застигнуты врасплох, когда вам придется иметь дело с импортом данных. Большинство задач чтения, обработки и записи CSV можно легко решить с помощью базовой библиотеки Pythoncsv. Если у вас есть много данных для чтения и обработки, библиотекаpandas также предоставляет быстрые и простые возможности обработки CSV.

__ Take the Quiz: Проверьте свои знания с помощью интерактивного теста «Чтение и запись файлов CSV на Python». По окончании вы получите оценку, чтобы вы могли отслеживать прогресс в обучении с течением времени:

Есть ли другие способы разбора текстовых файлов? Конечно! Такие библиотеки, какANTLR,PLY иPlyPlus, могут обрабатывать тяжелый синтаксический анализ, и если простые манипуляции сString не сработают, всегда есть регулярные выражения.

Но это темы для других статей ...

Related