Dodaj nagłówek w Pythonie do pliku csv

85

Napisałem skrypt Pythona łączący dwa pliki csv, a teraz chcę dodać nagłówek do końcowego pliku csv. Próbowałem następujące sugestie zgłaszane tutaj i mam następujący błąd: expected string, float found. Jaki jest najbardziej pythonowy sposób rozwiązania tego problemu?

Oto kod, którego używam:

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)
albus_c
źródło
ile kolumn piszesz w pliku csv? Czy mógłbyś podać w swoim pytaniu 1. format wejściowy pliku 2. format wyjściowy
nio
@nio: Duża część przesłanego kodu pochodzi z poprzedniego pytania OP
Martijn Pieters

Odpowiedzi:

116

DictWriter()Klasy oczekuje słowniki dla każdego rzędu. Jeśli wszystko, co chciałeś zrobić, to napisać początkowy nagłówek, użyj zwykłego csv.writer()i przekaż w prostym wierszu nagłówka:

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)

Alternatywą byłoby wygenerowanie słowników podczas kopiowania danych:

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)
Martijn Pieters
źródło
1
Dlaczego pliki są otwierane w trybie binarnym? Pliki csv mają oczywiście format tekstowy, a nie binarny. Może to powodować problemy w systemach Windows.
czarter
3
@pcarter: W Pythonie 2, otwarcie pliku w trybie tekstowym w systemie Windows wyzwala tłumaczenia nowej linii, które są niezgodne z formatem CSV; csvmoduł chce w ten sposób bezpośrednio (za pomocą obsługiwać nowe linie \n, a \r\nw razie potrzeby), co oznacza, że trzeba otworzyć plik w trybie binarnym. Zobacz csv.reader()dokumentację : Jeśli csvfile jest obiektem pliku, należy go otworzyć z flagą „b” na platformach, na których ma to znaczenie. . W Pythonie 3 zamiast tego newline=''użyłbyś tej opcji .
Martijn Pieters
To działa, zabawna rzecz: kiedy plik zostanie otwarty w atrybie, writer.writeheader()dwukrotnie zapisze nagłówek, mimo że wiersz nagłówka został już zapisany!
loretoparisi
2
@loretoparisi: oczywiście, że tak. Nie używaj writer.writeheader()podczas dołączania do istniejącego pliku. csv.writer()Obiekt nie może wykryć, że piszesz dane do istniejącego pliku.
Martijn Pieters
W Pythonie 3 otwarcie pliku z opcją 'w' jest potrzebne, binarny nie zadziała. Warto o tym wspomnieć w odpowiedzi. Znalazłem tę różnicę tutaj: stackoverflow.com/questions/34283178/…
Kristóf
7

Po prostu dodajesz jeden dodatkowy wiersz przed wykonaniem pętli. Ten wiersz zawiera nazwę nagłówka pliku 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])
Mitul Panchal
źródło
4

To zadziałało dla mnie.

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)
saggzz
źródło
1
używanie pliku jako zmiennej nie jest dobrym pomysłem. Wiersz nr 3. Zamiast tego użyj pliku csv lub innego.
Gorgonzola