2010-03-25 13 views
37

Faceci, mam tutaj 200 oddzielnych plików CSV nazwanych od SH (1) do SH (200). Chcę połączyć je w jeden plik csv. Jak mogę to zrobić?jak scalić 200 plików CSV w Pythonie

+2

W jaki sposób je scaliłeś? (Łącz linie ...) – tur1ng

+5

Jak chcesz je scalić? Każda linia w pliku CSV jest wierszem. Tak więc jedną prostą opcją jest po prostu połączenie wszystkich plików razem. –

+0

Każdy plik ma dwie kolumny. Chcę połączyć je w jeden plik z dwiema kolumnami kolejno. – Chuck

Odpowiedz

48

Jak ghostdog74 powiedział, ale tym razem z nagłówkami:

fout=open("out.csv","a") 
# first file: 
for line in open("sh1.csv"): 
    fout.write(line) 
# now the rest:  
for num in range(2,201): 
    f = open("sh"+str(num)+".csv") 
    f.next() # skip the header 
    for line in f: 
     fout.write(line) 
    f.close() # not really needed 
fout.close() 
+0

dzięki za to rozwiązanie! dokładnie to, czego szukałem! – Riccardo

+0

możesz użyć 'f .__ next __()' zamiast tego, jeśli 'f.next()' w python3.x. –

3

Jeśli połączony CSV ma być stosowany w Pythonie następnie wystarczy użyć glob aby uzyskać listę plików, aby przejść do fileinput.input() poprzez files argumentu, a następnie użyć modułu csv czytać to wszystko za jednym zamachem.

12
fout=open("out.csv","a") 
for num in range(1,201): 
    for line in open("sh"+str(num)+".csv"): 
     fout.write(line)  
fout.close() 
10

Zależy od tego, co masz na myśli przez "scalanie" - czy mają te same kolumny? Czy mają nagłówki? Na przykład, jeśli wszystkie mają te same kolumny i brak nagłówków, proste połączenie jest wystarczające (otwórz plik docelowy do zapisu, przeprowadź pętlę nad źródłami otwierającymi każdy do odczytu, użyj shutil.copyfileobj ze źródła otwartego do odczytu do przeznaczenie na piśmie, zamknij źródło, zachowaj pętlę - użyj instrukcji with, aby zamknąć w Twoim imieniu). Jeśli mają one te same kolumny, ale także nagłówki, w przypadku każdego pliku źródłowego będzie potrzebny readline, z wyjątkiem pierwszego, po otwarciu go do odczytu przed skopiowaniem do miejsca docelowego, aby pominąć wiersz nagłówków.

Jeśli w plikach CSV nie ma tych samych kolumn, należy określić, w jakim sensie je "łączymy" (np. SQL JOIN? Lub "poziomo", jeśli wszystkie mają tę samą liczbę linii itd. itd.) - trudno nam zgadywać, co masz na myśli w tej sprawie.

+0

Każdy plik ma dwie kolumny z nagłówkami. Chcę połączyć je w jeden plik z dwiema kolumnami kolejno. – Chuck

1

Można zaimportować CSV, a następnie zapętlić wszystkie pliki CSV, czytając je na liście. Następnie zapisz listę z powrotem na dysk.

import csv 

rows = [] 

for f in (file1, file2, ...): 
    reader = csv.reader(open("f", "rb")) 

    for row in reader: 
     rows.append(row) 

writer = csv.writer(open("some.csv", "wb")) 
writer.writerows("\n".join(rows)) 

Powyższe nie jest bardzo wytrzymała, ponieważ nie ma obsługi błędów ani nie zamknąć wszystkie otwarte pliki. Powinno to działać niezależnie od tego, czy poszczególne pliki zawierają jeden lub więcej wierszy danych CSV. Również nie uruchomiłem tego kodu, ale powinien dać ci pojęcie, co robić.

29

Dlaczego nie można po prostu sed 1d sh*.csv > merged.csv?

Czasami nie musisz nawet używać Pythona!

+9

W oknach, C: \> copy * .csv merged.csv –

+1

Skopiuj informacje nagłówka z jednego pliku: sed -n 1p some_file.csv> merged_file.csv Skopiuj wszystkie oprócz ostatniej linii ze wszystkich innych plików: sed 1d * .csv >> merged_file.csv – behas

+1

@blinsay Dodaje też nagłówek każdego pliku CSV do połączonego pliku. – Mina

10

Jestem po prostu będzie przez kolejny przykład kodu w koszu

from glob import glob 

with open('singleDataFile.csv', 'a') as singleFile: 
    for csvFile in glob('*.csv'): 
     for line in open(csvFile, 'r'): 
      singleFile.write(line) 
+2

@Andy Nie widzę różnicy między stackoverflow przypominając mi, aby głosować w górę odpowiedź i mnie przypominając ludziom, aby podzielić się ich uznaniem (przez głosowanie w górę), jeśli uznali moją odpowiedź za przydatną. Wiem, że to nie jest Facebook i nie jestem jak łowca .. – Norfeldt

+0

Został [omówiony] (http://meta.stackexchange.com/a/63440/186281) [poprzednio] (http: // meta.stackexchange.com/a/194063/186281) i za każdym razem został on [uznane] (http://meta.stackexchange.com/questions/167155/comments-asking-for-upvotes-accepts) niedopuszczalne. – Andy

+1

zobacz @adders poprawiony kod poniżej – mattrweaver

3

Nieznaczne zmiany w powyższym kodzie, ponieważ w rzeczywistości nie działa poprawnie.

Powinno być następujące ...

from glob import glob 

with open('main.csv', 'a') as singleFile: 
    for csv in glob('*.csv'): 
     if csv == 'main.csv': 
      pass 
     else: 
      for line in open(csv, 'r'): 
       singleFile.write(line) 
1

dość łatwo połączyć wszystkie pliki w katalogu i scalić je

import glob 
import csv 


# Open result file 
with open('output.txt','wb') as fout: 
    wout = csv.writer(fout,delimiter=',') 
    interesting_files = glob.glob("*.csv") 
    h = True 
    for filename in interesting_files: 
     print 'Processing',filename 
     # Open and process file 
     with open(filename,'rb') as fin: 
      if h: 
       h = False 
      else: 
       fin.next()#skip header 
      for line in csv.reader(fin,delimiter=','): 
       wout.writerow(line) 
8

Korzystając accepted StackOverflow answer stworzyć listę plików csv, który chcesz dołączyć, a następnie uruchomić ten kod:

import pandas as pd 
combined_csv = pd.concat([ pd.read_csv(f) for f in filenames ]) 

A jeśli chcesz wyeksportować go do pojedynczego pliku CSV, użyj:

combined_csv.to_csv("combined_csv.csv", index=False) 
+0

@ wisty, @ Andy, załóżmy, że wszystkie pliki mają tytuły dla każdego wiersza - niektóre wiersze z różnymi tytułami. Brak nagłówków dla 2 kolumn w każdym pliku. Jak można scalać, tak, że dla każdego pliku dodawana jest tylko kolumna. – Gathide

+0

Skąd plik jest eksportowany? – dirtysocks45

+0

@ dirtysocks45, zmieniłem odpowiedź, aby było to bardziej wyraźne. – scottlittle

0

I zmodyfikowane co @wisty mówi się, że pracował z Pythona 3.x, dla tych z was, którzy mają problemy kodowania, także używam moduł OS Aby uniknąć ciężko kodowania

import os 
def merge_all(): 
    dir = os.chdir('C:\python\data\\') 
    fout = open("merged_files.csv", "ab") 
    # first file: 
    for line in open("file_1.csv",'rb'): 
     fout.write(line) 
    # now the rest: 
    list = os.listdir(dir) 
    number_files = len(list) 
    for num in range(2, number_files): 
     f = open("file_" + str(num) + ".csv", 'rb') 
     f.__next__() # skip the header 
     for line in f: 
      fout.write(line) 
     f.close() # not really needed 
    fout.close() 
0

Oto scenariusz:

  • Konkatenowanie csv pliki o nazwie SH1.csv do SH200.csv
  • Utrzymanie nagłówki
import glob 
import re 

# Looking for filenames like 'SH1.csv' ... 'SH200.csv' 
pattern = re.compile("^SH([1-9]|[1-9][0-9]|1[0-9][0-9]|200).csv$") 
file_parts = [name for name in glob.glob('*.csv') if pattern.match(name)] 

with open("file_merged.csv","wb") as file_merged: 
    for (i, name) in enumerate(file_parts): 
     with open(name, "rb") as file_part: 
      if i != 0: 
       next(file_part) # skip headers if not first file 
      file_merged.write(file_part.read())