Пітонічно додайте заголовок у файл CSV


84

Я написав скрипт Python, що об'єднує два файли csv, і тепер я хочу додати заголовок до остаточного csv. Я спробував наступні пропозиції повідомили тут , і я отримав наступне повідомлення про помилку: expected string, float found. Який найбільш пітонічний спосіб це виправити?

Ось код, який я використовую:

import csv

with open('combined_file.csv', 'w', newline='') as outcsv:
    writer = csv.DictWriter(outcsv, fieldnames = ["Date", "temperature 1", "Temperature 2"])
    writer.writeheader()

    with open('t1.csv', 'r', newline='') as incsv:
        reader = csv.reader(incsv)
        writer.writerows(row + [0.0] for row in reader)

    with open('t2.csv', 'r', newline='') as incsv:
        reader = csv.reader(incsv)
        writer.writerows(row[:1] + [0.0] + row[1:] for row in reader)

скільки стовпців ви пишете у свій файл CSV? Не могли б ви вказати у своєму питанні 1. вхідний формат вашого файлу 2. вихідний формат
nio

@nio: Великий розділ розміщеного коду - з попереднього запитання ОП
Martijn Pieters

Відповіді:


115

DictWriter()Клас очікує , що словники для кожного рядка. Якщо все, що ви хотіли зробити, це написати початковий заголовок, використовуйте звичайний csv.writer()і передайте в простий рядок для заголовка:

import csv

with open('combined_file.csv', 'w', newline='') as outcsv:
    writer = csv.writer(outcsv)
    writer.writerow(["Date", "temperature 1", "Temperature 2"])

    with open('t1.csv', 'r', newline='') as incsv:
        reader = csv.reader(incsv)
        writer.writerows(row + [0.0] for row in reader)

    with open('t2.csv', 'r', newline='') as incsv:
        reader = csv.reader(incsv)
        writer.writerows(row[:1] + [0.0] + row[1:] for row in reader)

Альтернативою може бути створення словників під час копіювання даних:

import csv

with open('combined_file.csv', 'w', newline='') as outcsv:
    writer = csv.DictWriter(outcsv, fieldnames = ["Date", "temperature 1", "Temperature 2"])
    writer.writeheader()

    with open('t1.csv', 'r', newline='') as incsv:
        reader = csv.reader(incsv)
        writer.writerows({'Date': row[0], 'temperature 1': row[1], 'temperature 2': 0.0} for row in reader)

    with open('t2.csv', 'r', newline='') as incsv:
        reader = csv.reader(incsv)
        writer.writerows({'Date': row[0], 'temperature 1': 0.0, 'temperature 2': row[1]} for row in reader)

1
Чому файли відкриваються у двійковому режимі? Файли CSV, очевидно, є текстовим, а не двійковим форматом. Це може спричинити проблеми в системах Windows.
pcarter

3
@pcarter: На Python 2 відкриття файлу в текстовому режимі в Windows запускає переклади нового рядка, які несумісні з форматом CSV; csvтаким чином модуль хоче обробляти переклади рядків безпосередньо ( \nі \r\nв разі необхідності), що означає , що ви повинні відкрити файл в двійковому режимі. Дивіться csv.reader()документацію : Якщо csvfile є файловим об’єктом, його потрібно відкрити прапором 'b' на платформах, де це має значення. . На Python 3 замість цього ви б використали цю newline=''опцію .
Мартін Пітерс

Це працює, смішно: коли файл відкрито в aрежимі, writer.writeheader()він двічі запише заголовок, незважаючи на те, що рядок заголовка вже був написаний!
loretoparisi

2
@loretoparisi: звичайно, так. Не використовувати writer.writeheader()під час додавання до існуючого файлу. csv.writer()Об'єкт не може виявити , що ви пишете дані в існуючий файл.
Мартін Пітерс

У Python 3 потрібно відкрити файл з опцією 'w', двійковий файл не працюватиме. Було б корисно згадати про це у відповіді. Я знайшов цю різницю тут: stackoverflow.com/questions/34283178/…
Kristóf

6

Ви просто додаєте один додатковий рядок перед тим, як виконати цикл. Цей рядок містить назву заголовка вашого файлу CSV.

schema = ['a','b','c','b']
row = 4
generators = ['A','B','C','D']
with open('test.csv','wb') as csvfile:    
     writer = csv.writer(csvfile, delimiter=delimiter)
# Gives the header name row into csv
     writer.writerow([g for g in schema])   
#Data add in csv file       
     for x in xrange(rows):
         writer.writerow([g() for g in generators])

3

Це спрацювало для мене.

header = ['row1', 'row2', 'row3']
some_list = [1, 2, 3]
with open('test.csv', 'wt', newline ='') as file:
    writer = csv.writer(file, delimiter=',')
    writer.writerow(i for i in header)
    for j in some_list:
        writer.writerow(j)
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.