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

1 июня, 2020

Подписывайся на наш канал в Telegram, чтобы ежедневно совершенствоваться в Python. Там выходят задачи, полезные советы и сливы платных курсов - перейти

Оглавление

  • Что такое файл CSV?
    • Откуда берутся файлы CSV?
  • Разбор CSV-файлов с помощью встроенной библиотеки Python CSV
    • Чтение CSV-файлов с помощью CSV
    • Чтение файлов CSV в словарь с CSV
    • Дополнительные параметры чтения Python CSV
    • Написание файлов CSV с помощью CSV
    • Написание файла CSV из словаря с CSV
  • Разбор CSV-файлов с помощью библиотеки Pandas
    • Чтение CSV-файлов с помощью Pandas
    • Написание файлов CSV с помощью Pandas
  • Вывод

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

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

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

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

Пройдите тест: проверьте свои знания с помощью нашего интерактивного теста «Чтение и запись файлов 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
...

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

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

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

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

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

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

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

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

Чтение из файла CSV выполняется с использованием reader объекта. Файл CSV открывается как текстовый файл с помощью встроенной open() функции Python , которая возвращает объект файла. Это затем передается в 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 непосредственно в словарь (технически, Упорядоченный словарь ).

Опять же, наш входной файл 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необязательный параметр в список, содержащий их.

Необязательные readerпараметры Python CSV

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

  • 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 содержит три поля: nameaddress и date joined, которые через запятую. Проблема в том, что данные для address поля также содержат запятую для обозначения почтового индекса.

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

  • Используйте другой разделитель.
    Таким образом, запятую можно безопасно использовать в самих данных. Вы используете delimiterнеобязательный параметр, чтобы указать новый разделитель.
  • Заключите данные в кавычки
    . Особая природа выбранного вами разделителя игнорируется в строках в кавычках. Следовательно, вы можете указать символ, используемый для цитирования, с помощью quotechar необязательного параметра. Пока этот символ также не отображается в данных, все в порядке.
  • Экранирование символов-разделителей в данных
    Экранирование символов работает так же, как и в строках формата, сводя на нет интерпретацию экранированного символа (в данном случае, разделителя). Если используется 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 обязателен при написании словаря. Это имеет смысл, когда вы думаете об этом: без списка fieldnames, то DictWriterне может знать, какие ключи использовать для извлечения значений из ваших словарей. Он также использует ключи fieldnames для записи первой строки в качестве имен столбцов.

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

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

Разбор CSV-файлов с pandas библиотекой

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

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

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

$ conda install pandas

Как используется pip/pipenv для других случаев:

$ pip install pandas

Мы не будем углубляться в особенности того, как pandas работает или как его использовать. Для более подробной информации о том, как использовать pandas для чтения и анализа больших наборов данных.

Чтение CSV-файлов используя pandas

Чтобы продемонстрировать некоторые возможности pandas с CSV, я создал немного более сложный файл для чтения под названием 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 в pandas DataFrame быстро и просто:

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. Это потому, что мы не сказали, каким должен быть наш индекс.
  • Кроме того, если вы посмотрите на типы данных наших столбцов, вы увидите, что столбцы – Salary и правильно преобразованы в Sick Days remaining числа, но Hire Date столбец все еще является String. Это легко подтверждается в интерактивном режиме:
>>> print(type(df['Hire Date'][0])) <class 'str'>

Давайте решать эти проблемы по по порядку. Чтобы использовать другой столбец в качестве индекса 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]))
<class 'pandas._libs.tslibs.timestamps.Timestamp'>

Если ваши 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 легко выполняются базовой библиотекой Python csv. Если у вас есть много данных для чтения и обработки, pandas библиотека также предоставляет возможности быстрой и простой обработки CSV.

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


Совершенствуй знания каждый день у нас в Телеграм-каналах

Вопросы, реклама — VK | Telegram