Python'da 200 csv dosyası nasıl birleştirilir


83

Beyler, burada SH (1) - SH (200) arasında isimlendirilmiş 200 ayrı csv dosyası var. Bunları tek bir csv dosyasında birleştirmek istiyorum. Nasıl yapabilirim?


3
Onları ne şekilde birleştirirsiniz? (Satırları birleştir, ...)
tur1ng

6
Nasıl birleştirilmesini istersiniz? CSV dosyasındaki her satır bir satırdır. Dolayısıyla, basit bir seçenek, tüm dosyaları bir araya getirmektir.
Jon-Eric

Her dosyanın iki sütunu vardır. Bunları arka arkaya iki sütunlu tek bir dosyada birleştirmek istiyorum.
Chuck

1
@Chuck: Yorumlarınızdaki (soruya ve cevaplara) tüm yanıtları alıp sorunuzu güncellemeye ne dersiniz?
tumultous_rooster

2
Bu soru, "Nasıl adlı olmalıdır concat " nasıl yerine ... " birleştirme ..."
colidyre

Yanıtlar:


95

Ghostdog74'ün dediği gibi, ancak bu sefer başlıklarla:

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()

11
f.__next__()onun yerine f.next()python3.x içinde kullanabilirsiniz .
tsveti_iko

5
Sadece bir not: with openSözdizimi kullanılabilir ve .close()dosyaların manuel olarak girilmesi önlenebilir .
FatihAkici

2
f.next()ve arasındaki fark f.__next__()nedir? '_io.TextIOWrapper' object has no attribute 'next'
Jason Goal

fout.write(line)benden önce :if line[-1] != '\n': line += '\n'
shisui

65

Neden sadece yapamıyorsun sed 1d sh*.csv > merged.csv?

Bazen python kullanmak zorunda bile değilsin!


21
Windows'ta, C: \> copy * .csv merged.csv
hava saldırısı

6
Bir dosyadan başlık bilgisini kopyalayın: sed -n 1p some_file.csv> merged_file.csv Diğer tüm dosyalardan son satır hariç tümünü kopyalayın: sed 1d * .csv >> merged_file.csv
behas

3
@blinsay Her CSV dosyasındaki başlığı birleştirilmiş dosyaya da ekler.
Mina

5
Bu komutu, ilkinden sonraki her bir sonraki dosya için başlık bilgilerini kopyalamadan nasıl kullanıyorsunuz? Görünüşe göre üstbilgi bilgileri tekrar tekrar ortaya çıkıyor.
Joe

2
Başlığı çıkarmanız gerekmiyorsa bu harika!
Blairg23

51

Eklemek istediğiniz csv dosyalarının bir listesini oluşturmak için kabul edilen StackOverflow yanıtını kullanın ve ardından şu kodu çalıştırın:

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

Ve bunu tek bir csv dosyasına aktarmak istiyorsanız, şunu kullanın:

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

@ wisty, @ Andy, tüm dosyaların her satır için başlıklara sahip olduğunu varsayalım - farklı başlıklara sahip bazı satırlar. Her dosyadaki 2 sütun için başlık yok. Nasıl birleştirme, öyle ki her dosya için sadece bir sütun eklenir.
Gathide

Dosya nereye aktarılıyor?

@ dirtysocks45, bunu daha açık hale getirmek için cevabı değiştirdim.
scottlittle

sıralama ekle: birleşik_csv = pd.concat ([pd.read_csv (f) dosya adlarındaki f için], sırala = Yanlış)
sailfish009

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

13

Sepetteki başka bir kod örneğini inceleyeceğim

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 Stackoverflow'un bir cevabı oylamamı hatırlatması ile insanlara cevabımı faydalı buldukları takdirde takdirlerini paylaşmalarını (oy vererek) hatırlatmam arasındaki farkı göremiyorum. Bunun Facebook olmadığını biliyorum ve ben de benzer bir avcı değilim ..
Norfeldt

1
Bu edilmiş tartışılan daha önce ve olmuştur her zaman kabul edilemez.
Andy

10

"Birleştirme" ile ne demek istediğinize bağlı - aynı sütunlara mı sahipler? Başlıkları var mı? Örneğin, hepsi aynı sütunlara sahipse ve başlıkları yoksa, basit birleştirme yeterlidir (hedef dosyayı yazmak için açın, her birini okumak için açan kaynakların üzerinden döngü yapın, okuma için açık kaynağından shutil.copyfileobj dosyasını kullanın . yazmak için açık hedef, kaynağı kapatın, döngüye devam edin - withsizin adınıza kapatma yapmak için ifadeyi kullanın). Aynı sütunlara ve aynı zamanda başlıklara sahiplerse readline, başlık satırını atlamak için, hedefe kopyalamadan önce okumak için açtıktan sonra, ilki hariç her kaynak dosyada bir dosyaya ihtiyacınız olacaktır .

CSV dosyalarının tümü aynı sütunlara sahip değilse, onları hangi anlamda "birleştireceğinizi" tanımlamanız gerekir (bir SQL JOIN gibi mi? Veya hepsi aynı sayıda satıra sahipse "yatay olarak" mı? Vb.) ) - bu durumda ne demek istediğini tahmin etmek bizim için zor.


Her dosyanın başlıkları olan iki sütunu vardır. Bunları arka arkaya iki sütunlu tek bir dosyada birleştirmek istiyorum.
Chuck

4

Aslında doğru çalışmadığı için yukarıdaki kodda küçük bir değişiklik.

Aşağıdaki gibi olmalıdır ...

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)


3

Tüm dosyaları bir dizinde birleştirmek ve birleştirmek oldukça kolaydır

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)

3

Linux / mac üzerinde çalışıyorsanız, bunu yapabilirsiniz.

from subprocess import call
script="cat *.csv>merge.csv"
call(script,shell=True)


1

Csv'yi içe aktarabilir, ardından tüm CSV dosyalarını okuyarak bir listeye girebilirsiniz. Ardından listeyi diske geri yazın.

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))

Yukarıdakiler, herhangi bir hata işleme içermediğinden ve açık dosyaları kapatmadığından çok sağlam değildir. Bu, tek tek dosyaların içlerinde bir veya daha fazla CSV verisi satırı olup olmadığına bakılmaksızın çalışmalıdır. Ayrıca bu kodu ben çalıştırmadım, ancak size ne yapmanız gerektiği konusunda bir fikir vermeli.


1

@Adders'ı oluşturan ve daha sonra @varun tarafından geliştirilen çözüm üzerinde, bazı küçük iyileştirmeler de uyguladım, tüm birleştirilmiş CSV'yi yalnızca ana başlık ile bıraktım:

from glob import glob

filename = 'main.csv'

with open(filename, 'a') as singleFile:
    first_csv = True
    for csv in glob('*.csv'):
        if csv == filename:
            pass
        else:
            header = True
            for line in open(csv, 'r'):
                if first_csv and header:
                    singleFile.write(line)
                    first_csv = False
                    header = False
                elif header:
                    header = False
                else:
                    singleFile.write(line)
    singleFile.close()

Saygılarımla!!!


1

Sadece yerleşik csvkitaplığı kullanabilirsiniz. Bu çözüm, en çok oy alan diğer yanıtların aksine, CSV dosyalarınızdan bazıları biraz farklı sütun adlarına veya başlıklara sahip olsa bile işe yarayacaktır.

import csv
import glob


filenames = [i for i in glob.glob("SH*.csv")]
header_keys = []
merged_rows = []

for filename in filenames:
    with open(filename) as f:
        reader = csv.DictReader(f)
        merged_rows.extend(list(reader))
        header_keys.extend([key for key in reader.fieldnames if key not in header_keys])

with open("combined.csv", "w") as f:
    w = csv.DictWriter(f, fieldnames=header_keys)
    w.writeheader()
    w.writerows(merged_rows)

Birleştirilmiş dosya header_keys, dosyalarda bulunabilecek olası tüm sütunları ( ) içerecektir . Bir dosyadaki eksik sütunlar boş / boş olarak işlenir (ancak dosyanın geri kalanı korunur).

Not:

  • CSV dosyalarınızın üst bilgisi yoksa bu işe yaramaz. Bu durumda, csvkitaplığı yine de kullanabilirsiniz , ancak DictReader& kullanmak yerine DictWriter, temel reader& ile çalışmanız gerekir writer.
  • İçeriğin tamamı bellekte ( merged_rowsliste) depolandığından, büyük verilerle uğraşırken bu sorunlara neden olabilir .

0

@Wisty'nin python 3.x ile çalıştığını söylediği şeyi değiştirdim, kodlama sorunu olanlar için, ayrıca sabit kodlamadan kaçınmak için os modülünü kullanıyorum

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

İşte bir komut dosyası:

  • Birleştirilmesi CSV adlı dosyaları SH1.csviçinSH200.csv
  • Başlıkları tutmak
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())

0

Wisy'nin python3 için cevabını güncelleme

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")
    next(f) # skip the header
    for line in f:
         fout.write(line)
    f.close() # not really needed
fout.close()

0

Diyelim ki buna benzer 2 csvdosyanız var :

csv1.csv:

id,name
1,Armin
2,Sven

csv2.csv:

id,place,year
1,Reykjavik,2017
2,Amsterdam,2018
3,Berlin,2019

ve sonucun şu csv3.csv gibi olmasını istiyorsunuz:

id,name,place,year
1,Armin,Reykjavik,2017
2,Sven,Amsterdam,2018
3,,Berlin,2019

Ardından bunu yapmak için aşağıdaki parçacığı kullanabilirsiniz:

import csv
import pandas as pd

# the file names
f1 = "csv1.csv"
f2 = "csv2.csv"
out_f = "csv3.csv"

# read the files
df1 = pd.read_csv(f1)
df2 = pd.read_csv(f2)

# get the keys
keys1 = list(df1)
keys2 = list(df2)

# merge both files
for idx, row in df2.iterrows():
    data = df1[df1['id'] == row['id']]

    # if row with such id does not exist, add the whole row
    if data.empty:
        next_idx = len(df1)
        for key in keys2:
            df1.at[next_idx, key] = df2.at[idx, key]

    # if row with such id exists, add only the missing keys with their values
    else:
        i = int(data.index[0])
        for key in keys2:
            if key not in keys1:
                df1.at[i, key] = df2.at[idx, key]

# save the merged files
df1.to_csv(out_f, index=False, encoding='utf-8', quotechar="", quoting=csv.QUOTE_NONE)

Bir döngü yardımıyla, birden çok dosya için sizin durumunuzda olduğu gibi aynı sonucu elde edebilirsiniz (200 csv dosyası).


0

Dosyalar sırayla numaralandırılmamışsa, aşağıdaki sorunsuz yaklaşımı uygulayın: Windows makinesinde Python 3.6:

import pandas as pd
from glob import glob

interesting_files = glob("C:/temp/*.csv") # it grabs all the csv files from the directory you mention here

df_list = []
for filename in sorted(interesting_files):

df_list.append(pd.read_csv(filename))
full_df = pd.concat(df_list)

# save the final file in same/different directory:
full_df.to_csv("C:/temp/merged_pandas.csv", index=False)

0

Kullanımı kolay bir işlev:

def csv_merge(destination_path, *source_paths):
'''
Merges all csv files on source_paths to destination_path.
:param destination_path: Path of a single csv file, doesn't need to exist
:param source_paths: Paths of csv files to be merged into, needs to exist
:return: None
'''
with open(destination_path,"a") as dest_file:
    with open(source_paths[0]) as src_file:
        for src_line in src_file.read():
            dest_file.write(src_line)
    source_paths.pop(0)
    for i in range(len(source_paths)):
        with open(source_paths[i]) as src_file:
            src_file.next()
            for src_line in src_file:
                 dest_file.write(src_line)

0
import pandas as pd
import os

df = pd.read_csv("e:\\data science\\kaggle assign\\monthly sales\\Pandas-Data-Science-Tasks-master\\SalesAnalysis\\Sales_Data\\Sales_April_2019.csv")
files = [file for file in  os.listdir("e:\\data science\\kaggle assign\\monthly sales\\Pandas-Data-Science-Tasks-master\\SalesAnalysis\\Sales_Data")
for file in files:
    print(file)

all_data = pd.DataFrame()
for file in files:
    df=pd.read_csv("e:\\data science\\kaggle assign\\monthly sales\\Pandas-Data-Science-Tasks-master\\SalesAnalysis\\Sales_Data\\"+file)
    all_data = pd.concat([all_data,df])
    all_data.head()
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.