Как записывать столбцы в питоне csv
Одним из распространенных файловых форматов, которые хранят в удобном виде информацию, является формат csv . Каждая строка в файле csv представляет отдельную запись или строку, которая состоит из отдельных столбцов, разделенных запятыми. Собственно поэтому формат и называется Comma Separated Values. Но хотя формат csv — это формат текстовых файлов, Python для упрощения работы с ним предоставляет специальный встроенный модуль csv .
Рассмотрим работу модуля на примере:
import csv FILENAME = "users.csv" users = [ ["Tom", 28], ["Alice", 23], ["Bob", 34] ] with open(FILENAME, "w", newline="") as file: writer = csv.writer(file) writer.writerows(users) with open(FILENAME, "a", newline="") as file: user = ["Sam", 31] writer = csv.writer(file) writer.writerow(user)
В файл записывается двухмерный список — фактически таблица, где каждая строка представляет одного пользователя. А каждый пользователь содержит два поля — имя и возраст. То есть фактически таблица из трех строк и двух столбцов.
При открытии файла на запись в качестве третьего параметра указывается значение newline=»» — пустая строка позволяет корректно считывать строки из файла вне зависимости от операционной системы.
Для записи нам надо получить объект writer , который возвращается функцией csv.writer(file) . В эту функцию передается открытый файл. А собственно запись производится с помощью метода writer.writerows(users) Этот метод принимает набор строк. В нашем случае это двухмерный список.
Если необходимо добавить одну запись, которая представляет собой одномерный список, например, [«Sam», 31] , то в этом случае можно вызвать метод writer.writerow(user)
В итоге после выполнения скрипта в той же папке окажется файл users.csv, который будет иметь следующее содержимое:
Tom,28 Alice,23 Bob,34 Sam,31
Для чтения из файла нам наоборот нужно создать объект reader :
import csv FILENAME = "users.csv" with open(FILENAME, "r", newline="") as file: reader = csv.reader(file) for row in reader: print(row[0], " - ", row[1])
При получении объекта reader мы можем в цикле перебрать все его строки:
Tom - 28 Alice - 23 Bob - 34 Sam - 31
Работа со словарями
В примере выше каждая запись или строка представляла собой отдельный список, например, [«Sam», 31] . Но кроме того, модуль csv имеет специальные дополнительные возможности для работы со словарями. В частности, функция csv.DictWriter() возвращает объект writer, который позволяет записывать в файл. А функция csv.DictReader() возвращает объект reader для чтения из файла. Например:
import csv FILENAME = "users.csv" users = [ , , ] with open(FILENAME, "w", newline="") as file: columns = ["name", "age"] writer = csv.DictWriter(file, fieldnames=columns) writer.writeheader() # запись нескольких строк writer.writerows(users) user = # запись одной строки writer.writerow(user) with open(FILENAME, "r", newline="") as file: reader = csv.DictReader(file) for row in reader: print(row["name"], "-", row["age"])
Запись строк также производится с помощью методов writerow() и writerows() . Но теперь каждая строка представляет собой отдельный словарь, и кроме того, производится запись и заголовков столбцов с помощью метода writeheader() , а в метод csv.DictWriter в качестве второго параметра передается набор столбцов.
При чтении строк, используя названия столбцов, мы можем обратиться к отдельным значениям внутри строки: row[«name»] .
Модуль csv — чтение и запись CSV файлов
Формат CSV (Comma Separated Values) является одним из самых распространенных форматов импорта и экспорта электронных таблиц и баз данных. CSV использовался в течение многих лет до того, как был стандартизирован в RFC 4180. Запоздание четко определенного стандарта означает, что в данных, создаваемых различными приложениями, часто существуют незначительные различия. Эти различия могут вызвать раздражение при обработке файлов CSV из нескольких источников. Тем не менее, хотя разделители, символы кавычек и некоторые другие свойства различаются, общий формат достаточно универсален. Значит, возможно написать один модуль, который может эффективно манипулировать такими данными, скрывая детали чтения и записи данных от программиста.
Функции обработки CSV-файлов
csv.reader(csvfile, dialect=’excel’, **fmtparams) — возвращает объект reader, который построчно итерирует csvfile. Если csvfile является файловым объектом, то его нужно открыть с параметром newline=». Дополнительный параметр dialect используется для определения ряда параметров, характерных для специфического CSV диалекта. Он может быть подклассом Dialect или одной из строк, возвращаемой функцией list_dialects(). Также могут передаваться дополнительные ключевые аргументы fmtparams для переопределения отдельных параметров форматирования в текущем диалекте.
Каждая строка, считанная из файла csv, возвращается в виде списка строк. Автоматическое преобразование типов данных не выполняется, если не указан параметр формата QUOTE_NONNUMERIC (в этом случае все поля без кавычек преобразуются в числа с плавающей точкой).
Короткий пример использования:
csv.writer(csvfile, dialect=’excel’, **fmtparams) — возвращает объект writer, конвертирующий пользовательские данные в CSV-файл csvfile. csvfile может быть любым объектом с методом write(). Если csvfile является файловым объектом, то его нужно открыть с параметром newline=». Параметры dialect и fmtparams идентичны параметрам в функции csv.reader.
Необходимые методы экземпляра класса writer:
csvwriter.writerow(row) — записывает данные, представляющие одну строку CSV в файл, форматируя согласно текущему диалекту writer.
csvwriter.writerows(rows) — записывает данные, представляющие несколько строк CSV в файл, форматируя согласно текущему диалекту writer.
Пример использования writer :
csv.field_size_limit([new_limit]) — текущий максимальный размер поля. Если задан new_limit, то он становится новым макс. размером.
class csv.DictReader(f, fieldnames=None, restkey=None, restval=None, dialect=’excel’, *args, **kwds) — как reader, но отображает информацию о столбцах в словарь, ключи которого заданы в параметре fieldnames.
fieldnames это последовательность ключей. Если параметр опущен, в качестве ключей используются значения из первой строки файла. Если строка имеет больше полей, чем длина fieldnames , оставшиеся данные будут помещены в список с ключом из переменной restkey . Если строка имеет меньше полей, оставшиеся значения будут установлены в значение restval .
Остальные аргументы пробрасываются далее в экземпляр reader.
class csv.DictWriter(f, fieldnames, restval=», extrasaction=’raise’, dialect=’excel’, *args, **kwds) — как writer, но отображает словари в CSV-файл.
Обязательный параметр fieldnames — последовательность ключей, определяющие порядок, в котором значения из словаря будут записаны в строке CSV-файла f.
Параметр restval определяет значение в случае, если в словаре будет отсутствовать запись с данным ключом. Если словарь содержит лишние ключи, то поведение определяется параметром extrasaction . Если он ‘raise’, то выдаст ошибку. Если ‘ignore’, то такие ключи игнорируются.
Остальные аргументы пробрасываются далее в экземпляр writer.
Помимо методов writerow и writerows, DictWriter имеет также метод
DictWriter.writeheader() — записывает данные строки заголовка в CSV-файл, форматируя согласно текущему диалекту writer.
Пример использования DictWriter:
class csv.Dialect — для упрощения задания формата входных и выходных записей, конкретные параметры форматирования группируются в диалекты, подклассы csv.Dialect . Диалекты поддерживают следующие атрибуты:
Dialect.delimiter — разделитель столбцов в строке CSV-файла. По умолчанию ‘,’.
Dialect.quotechar — символ, использующийся для «склейки» поля, содержащего специальные символы, такие как delimiter, quotechar, или символы новой строки. По умолчанию используется значение ‘»‘.
Dialect.doublequote — как Dialect.quotechar , появляющийся внутри поля, должен экранироваться. Когда True, символ удваивается. Когда False, Dialect.escapechar используется как префикс к quotechar. По умолчанию True.
При записи файла, если doublequote=False и не установлен escapechar, выдаст ошибку при обнаружении quotechar в столбце.
Dialect.escapechar — символ, используемый writer для экранирования delimiter , если quoting установлен в QUOTE_NONE и quotechar , если doublequote=False . При чтении escapechar удаляет какое-либо особое значение со следующего символа. По умолчанию используется значение None, которое отключает экранирование.
Dialect.lineterminator — символы, используемые для завершения строки при записи. По умолчанию ‘\r\n’.
Dialect.skipinitialspace — если True, пробелы, непосредственно следующие за delimiter, игнорируются. Значение по умолчанию — False.
Dialect.strict — когда True, поднимает исключение если CSV файл не распознается. По умолчанию — False.
Dialect.quoting — контролирует, когда кавычки должны генерироваться writer и распознаваться reader. Он может принимать любые константы QUOTE_* и по умолчанию имеет значение QUOTE_MINIMAL.
csv.QUOTE_ALL — writer оборачивает в кавычки все поля.
csv.QUOTE_MINIMAL — writer оборачивает в кавычки только поля, содержащие специальные символы (delimiter, quotechar, lineterminator).
csv.QUOTE_NONNUMERIC — writer оборачивает в кавычки все поля, не являющиеся числами. reader преобразует все поля без кавычек к типу float.
csv.QUOTE_NONE — writer не оборачивает никакие поля в кавычки. Если в данных попадается delimiter или lineterminator, он предваряется символом escapechar, если установлен (исключение, если не установлен). reader не обрабатывает кавычки.
csv.register_dialect(name[, dialect[, **fmtparams]]) — связывает dialect с именем name. Подробности о диалектах см. в разделе «Диалекты и параметры форматирования»
csv.unregister_dialect(name) — удаляет связь диалекта с данным именем.
csv.get_dialect(name) — возвращает класс диалекта, свзанного с именем name.
csv.list_dialects() — список доступных диалектов. На данный момент это ‘excel’, ‘excel-tab’, ‘unix’.
Предустановленные диалекты
class csv.excel — диалект CSV-файла, обычно генерируемого программой Excel.
class csv.excel_tab — диалект CSV-файла, обычно генерируемого программой Excel с настройкой «разделитель с помощью TAB».
class csv.unix_dialect — диалект CSV-файла, обычно генерируемого в UNIX-системах (‘\n’ для новой строки, закавычивание всех полей).
Определение диалекта
class csv.Sniffer — используется для угадывания диалекта CSV-файла. Имеет следующие методы:
csvsniffer.sniff(sample, delimiters=None) — анализирует пример и возвращает Dialect, соответствующий обнаруженным параметрам. Если задан параметр delimiters , он интерпретируется как все возможные разделители.
csvsniffer.has_header(sample) — анализирует текст и возвращает True, если первая строка похожа на строку заголовков.
Методы определения диалекта являются эвристическими; это означает, что Sniffer может ошибаться.
Пример использования Sniffer:
Примеры
Простейший пример чтения CSV файла:
Чтение файла формата passwd:
Простейший пример записи CSV файла:
Для вставки кода на Python в комментарий заключайте его в теги
- Модуль csv - чтение и запись CSV файлов
- Создаём сайт на Django, используя хорошие практики. Часть 1: создаём проект
- Онлайн-обучение Python: сравнение популярных программ
- Книги о Python
- GUI (графический интерфейс пользователя)
- Курсы Python
- Модули
- Новости мира Python
- NumPy
- Обработка данных
- Основы программирования
- Примеры программ
- Типы данных в Python
- Видео
- Python для Web
- Работа для Python-программистов
- Сделай свой вклад в развитие сайта!
- Самоучитель Python
- Карта сайта
- Отзывы на книги по Python
- Реклама на сайте
На Python Как записать данные в несколько столбцов CSV?
Добрый день, написал код, который позволяет собирать данные с конфига XML и записывает эти данные в CSV - Таблицу. Не получается разобраться, почему у меня все данные записываются в один столбец. Решение есть, что в Excel я сделал "Разделить по столбцам" ориентир запятая и данные записались верно. Но хотелось бы узнать, где проблема в коде.
import xmltodict import csv with open("XML-FILE", "r") as cfg: dict = xmltodict.parse(cfg.read()) num = 1 with open('ACL.csv', 'w', newline="") as acl_file: fieldnames = ["ID","Order","Enabled", "Name", "Description", "IpVersion", "Src", "Dst", "Proxy", "Service", "ValidTime", "Action", "NAT", "SNAT", "DNAT"] listitem = dict['config']['list']['listitem'] writer = csv.DictWriter(acl_file, fieldnames=fieldnames, delimiter=',') writer.writeheader() for i in listitem: Dubl_name_ID = False Dubl_name_Order = False Dubl_name_Enabled = False Dubl_name_Name = False Dubl_name_Description = False Dubl_name_IpVersion = False Dubl_name_Src = False Dubl_name_Dst = False Dubl_name_Proxy = False Dubl_name_Service = False Dubl_name_Validtime = False Dubl_name_Action = False Dubl_name_NAT = False Dubl_name_SNAT = False Dubl_name_DNAT = False line = <> for j in i['variable']: try: text = j["#text"] except KeyError: text = "None" if j["@name"] == "Id": if Dubl_name_ID is False: line["ID"] = text elif Dubl_name_ID is True: line["ID"] = line["ID"] + "*" + text Dubl_name_ID is True if j["@name"] == "Order": if Dubl_name_Order is False: line["Order"] = text elif Dubl_name_Order is True: line["Order"] = line["Order"] + "*" + text Dubl_name_Order = True if j["@name"] == "Enabled": if Dubl_name_Enabled is False: line["Enabled"] = text elif Dubl_name_Enabled is True: line["Enabled"] = line["Enabled"] + "*" + text Dubl_name_Enabled = True if j["@name"] == "Name": if Dubl_name_Name is False: line["Name"] = text elif Dubl_name_Name is True: line["Name"] = line["Name"] + "*" + text Dubl_name_Name = True if j["@name"] == "Description": if Dubl_name_Description is False: line["Description"] = text elif Dubl_name_Description is True: line["Description"] = line["Description"] + "*" + text Dubl_name_Description = True if j["@name"] == "IpVersion" : if Dubl_name_IpVersion is False: line["IpVersion"] = text elif Dubl_name_IpVersion is True: line["IpVersion"] = line["IpVersion"] + "*" + text Dubl_name_IpVersion = True if j["@name"] == "Src": if Dubl_name_Src is False: line['Src'] = text elif Dubl_name_Src is True: line['Src'] = line['Src'] + "*" + text Dubl_name_Src = True if j["@name"] == "Dst" : if Dubl_name_Dst is False: line['Dst'] = text elif Dubl_name_Dst is True: line['Dst'] = line['Dst'] + "*" + text Dubl_name_Dst = True if j["@name"] == "Proxy": if Dubl_name_Proxy is False: line['Proxy'] = text elif Dubl_name_Proxy is True: line['Proxy'] = line['Proxy'] + "*" + text Dubl_name_Proxy = True if j["@name"] == "Service" : if Dubl_name_Service is False: line['Service'] = text elif Dubl_name_Service is True: line['Service'] = line['Service'] + "*" + text Dubl_name_Service = True if j["@name"] == "ValidTime" : if Dubl_name_Validtime is False: line['ValidTime'] = text elif Dubl_name_Validtime is True: line['ValidTime'] = line['ValidTime'] + text Dubl_name_Validtime = True if j["@name"] == "Action" : if Dubl_name_Action is False: line['Action'] = text elif Dubl_name_Action is True: line['Action'] = line['Action'] + "*" + text Dubl_name_Action = True if j["@name"] == "NAT": if Dubl_name_NAT is False: line['NAT'] = text elif Dubl_name_NAT is True: line['NAT'] = line['NAT'] + "*" + text Dubl_name_NAT = True if j["@name"] == "SNAT" : if Dubl_name_SNAT is False: line['SNAT'] = text elif Dubl_name_SNAT is True: line['SNAT'] = line['SNAT'] + "*" + text Dubl_name_SNAT = True if j["@name"] == "DNAT" : if Dubl_name_DNAT is False: line['DNAT'] = text elif Dubl_name_DNAT is True: line['DNAT'] = line['DNAT'] + "*" + text Dubl_name_DNAT = True num+=1 writer.writerow(line) acl_file.close() cfg.close()
P.S. Я не умею хорошо писать коды. Если покажите, как бы стоило более читабельно его написать, будет замечательно.
- Вопрос задан более двух лет назад
- 1139 просмотров
Комментировать
Решения вопроса 1
О каком "столбце" идет речь? CSV - файл, это обычный ТЕКСТОВЫЙ файл, в котором просто "по договоренности" все данные делятся разделителем. Не более.
Поэтому если вы просто открываете этот файл в MS EXCEL совершенно очевидно, что каждая запись будет представляться одной строчкой, которая попадает в один - как правило первый - столбец таблицы.
Если вы хотите с таким файлом в дальнейшем работать именно как с таблицей, то уже в EXCEL вам надо осуществить импорт данных их csv в xslx формат. Делается этот так:
Вкладка "Данные" -> Получение внешних данных ->Из текста->указываете имя вашего csv- файла ->выбераете формат "с разделителем"->Далее->выбираете используемый разделитель (например "запятая")->Далее->Готово->указываете место на листе, с которого импортированная таблица должна начинаться (обычно "=$A$1")->ОК
и смотрите, что у вас получилось в вашей теперь уже настоящей таблице EXCEL.
Ответ написан более двух лет назад
Maloyyy @Maloyyy Автор вопроса
Спасибо за ответ, да я так и сделал. До этого не знал, что CSV это просто текстовый файл.
Ответы на вопрос 0
Ваш ответ на вопрос
Войдите, чтобы написать ответ

- Python
- +2 ещё
TypeError: event_list() missing 1 required positional argument: 'call_data" aiogram при использовании CallbackFactory?
- 1 подписчик
- 3 часа назад
- 4 просмотра
Чтение и запись табличных данных в файловую систему — Python: Pandas
Библиотека Pandas разрабатывалась для работы с табличными данными. Популярными типами файлов для их хранения являются:
- csv — текстовый формат, в котором значения в столбцах отделены друг от друга разделителем, часто запятой
- xlsx или xls — форматы файлов электронных таблиц Microsoft Excel
Для чтения и записи таблиц в указанные форматы в Pandas существуют специальные методы. О них пойдет речь в этом уроке.
Чтение данных
Начнем работу с продажами в сети из четырех магазинов за одну неделю, которые хранятся в формате csv с запятой в качестве разделителя. Воспользуемся методом read_csv() :
df_orders = pd.read_csv('./data/Shop_orders.csv') print(df_orders.head()) # => Weekday Shop_1 Shop_2 Shop_3 Shop_4 # 0 mon 7 1 7 8 # 1 tue 4 2 4 5 # 2 wed 3 5 2 3 # 3 thu 8 12 8 7 # 4 fri 15 11 13 9
При чтении данных метод не знает, что считать за индекс в данных, поэтому расставляет индексы самостоятельно. Это возрастающая последовательность целых чисел, которая начинается с нуля. В нашем примере явным индексом является первый столбец — Weekday. Дополним метод параметром index_col с явным указанием номера столбца, который хранит индексы:
df_orders = pd.read_csv('./data/Shop_orders.csv', index_col=0) print(df_orders.head()) # => Shop_1 Shop_2 Shop_3 Shop_4 # Weekday # mon 7 1 7 8 # tue 4 2 4 5 # wed 3 5 2 3 # thu 8 12 8 7 # fri 15 11 13 9
У разделителя в данных формата csv есть важное значение при чтении. По умолчанию это запятая. Попытка считать данные с разделителем в виде точки с запятой приведет к некорректному чтению. В примере ниже в результате получается пустой DataFrame , в котором индексами стали данные в строках — не то, что хотелось получить:
df_orders = pd.read_csv('./data/Shop_orders_sep.csv', index_col=0) print(df_orders.head()) # => Empty DataFrame # Columns: [] # Index: [mon;7;1;7;8, tue;4;2;4;5, wed;3;5;2;3, thu;8;12;8;7, fri;15;11;13;9]
Для корректного чтения в данном случае достаточно воспользоваться параметром sep :
df_orders = pd.read_csv('./data/Shop_orders_sep.csv', index_col=0, sep=';') print(df_orders.head()) # => Shop_1 Shop_2 Shop_3 Shop_4 # Weekday # mon 7 1 7 8 # tue 4 2 4 5 # wed 3 5 2 3 # thu 8 12 8 7 # fri 15 11 13 9
Иногда описание данных может предшествовать началу самих табличных данных. В примере ниже файл начинается со строк:
Попытка прочитать данный файл повлечет ошибку:
df_orders = pd.read_csv('./data/Shop_orders_abstract.csv', index_col=0) print(df_orders.head()) # => ParserError: Error tokenizing data. C error: Expected 1 fields in line 4, saw 5
Чтобы пропустить ряд строк с описанием, нужно воспользоваться параметром skiprows . Его значение — это количество опускаемых из рассмотрения первых строк в файле:
df_orders = pd.read_csv('./data/Shop_orders_abstract.csv', index_col=0, skiprows=3) print(df_orders.head()) # => Shop_1 Shop_2 Shop_3 Shop_4 # Weekday # mon 7 1 7 8 # tue 4 2 4 5 # wed 3 5 2 3 # thu 8 12 8 7 # fri 15 11 13 9
Запись данных
После чтения и трансформации данных результаты могут быть сохранены в файловую систему. Для этого в Pandas есть ряд специальных методов. Для рассматриваемых типов данных это to_csv() и to_excel() :
df_orders.to_csv('./data/Shop_orders_restore.csv')
В примере выше метод to_csv() позволяет сохранить DataFrame в изначальном виде. Если в качестве индекса сохранить значения, которые присвоены Pandas по умолчанию, то это может мешать дальнейшему чтению и обработке. Также такие индексы не несут важной информации.
У нас есть такие данные:
# => Weekday Shop_1 Shop_2 Shop_3 Shop_4 # 0 mon 7 1 7 8 # 1 tue 4 2 4 5 # 2 wed 3 5 2 3 # 3 thu 8 12 8 7 # 4 fri 15 11 13 9
Для них с индексами по умолчанию достаточно воспользоваться параметром index , чтобы не сохранять их файл:
df_orders.to_csv('./data/Shop_orders_restore.csv', index=False)
В команде разработки можно проговорить, что будет использоваться в качестве разделителя в csv-файле. Также это может быть продиктовано совместимостью с другими частями программного продукта. Чтобы задать разделитель, нужно использовать параметр sep :
df_orders.to_csv('./data/Shop_orders_restore_sep.csv', index=False, sep=';')
Метод to_excel() позволяет сохранять табличные данные в формат MS Excel. Параметризация аналогична методу to_csv() . Меняется только название метода и расширение файла с .csv на .xlsx :
df_orders.to_excel('./data/Shop_orders_restore.xlsx', index=False)
В некоторых случаях сохранение названий столбцов также можно отключить. Это может потребоваться, когда нужно сохранить значения в ячейках таблицы, или когда названия столбцов не несут дополнительной информации, и не предполагается их использование. Для этого достаточно задать параметр header значением False:
df_orders.to_excel('./data/Shop_orders_restore_noheader.xlsx', index=False, header=False)
Большие таблицы текстовых данных занимают большой объем. Чтобы уменьшить его, можно создавать архивы методами Pandas. Для этого нужно определить метод сжатия и названия файла в архиве, при этом указать их в виде словаря в параметре compression :
df_orders.to_csv( './data/Shop_orders_restore.zip', index=False, compression='method': 'zip', 'archive_name': 'Shop_orders_restore_archive.csv'> )
Выводы
Данные для долгосрочного хранения размещают в виде файлов на жестких дисках. В данном уроке методами библиотеки Pandas выполнялись операции чтения и записи csv и xlsx файлов — наиболее популярных форматов хранения табличных данных.
Данные форматы позволяют хранить таблицы в структурированной форме, но при этом данная форма может сильно варьироваться:
- Могут использоваться различные варианты разделителей значений в столбцах
- Строки описания данных могут появляться в шапке таблице
- Индексы могут храниться не в привычном крайнем левом столбце
В уроке на практических примерах показано, как действовать в таких ситуациях. Конфигурацией параметров методов мы научились:
- Пропускать первые строки в таблице
Открыть доступ
Курсы программирования для новичков и опытных разработчиков. Начните обучение бесплатно
- 130 курсов, 2000+ часов теории
- 1000 практических заданий в браузере
- 360 000 студентов
Наши выпускники работают в компаниях:
