파이썬에서 200 개의 csv 파일을 병합하는 방법


82

여러분, 여기에는 SH (1)에서 SH (200)까지 이름이 지정된 200 개의 개별 csv 파일이 있습니다. 단일 csv 파일로 병합하고 싶습니다. 어떻게하니?


3
어떤 방식으로 병합 하시겠습니까? (줄 연결, ...)
tur1ng

6
어떻게 병합 하시겠습니까? CSV 파일의 각 행은 행입니다. 따라서 한 가지 간단한 옵션은 모든 파일을 함께 연결하는 것입니다.
Jon-Eric

각 파일에는 두 개의 열이 있습니다. 연속적으로 두 개의 열이있는 단일 파일로 병합하고 싶습니다.
Chuck

1
@Chuck : 귀하의 의견 (질문 및 답변)에있는 모든 응답을 취하고 질문을 업데이트하는 방법은 어떻습니까?
tumultous_rooster

1
이 질문은 "어떻게에 이름을 지정해야합니다 CONCAT "하는 방법 대신에 ... " 병합 ..."
colidyre

답변:


92

ghostdog74가 말했듯이 이번에는 헤더가 있습니다.

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
python3.x에서 f.__next__()대신 사용할 수 있습니다 f.next().
tsveti_iko

5
참고 사항 : with open구문을 사용 .close()하고 파일을 수동으로 처리하지 않아도됩니다.
FatihAkici

2
f.next()과 의 차이점은 무엇 f.__next__()입니까? 전자를 사용하면 다음과 같은 결과를 얻었습니다'_io.TextIOWrapper' object has no attribute 'next'
Jason Goal

fout.write(line)내가 하기 전에 :if line[-1] != '\n': line += '\n'
shisui

64

왜 안돼 sed 1d sh*.csv > merged.csv ?

때로는 파이썬을 사용할 필요조차 없습니다!


21
Windows에서 C : \> 복사 * .csv merged.csv
2011 년

5
한 파일에서 헤더 정보를 복사합니다. sed -n 1p some_file.csv> merged_file.csv 다른 모든 파일에서 마지막 줄을 제외하고 모두 복사합니다. sed 1d * .csv >> merged_file.csv
behas

3
@blinsay 병합 된 파일에도 각 CSV 파일의 헤더를 추가합니다.
Mina 2014 년

5
첫 번째 파일 이후의 각 후속 파일에 대한 헤더 정보를 복사하지 않고이 명령을 어떻게 사용합니까? 헤더 정보가 반복적으로 팝업되는 것 같습니다.

2
헤더를 제거 할 필요가없는 경우 유용합니다!
Blairg23

50

사용하다 StackOverflow의 답변을 받아 당신이 추가 한 후이 코드를 실행하려는 CSV 파일의 목록을 만들 수 :

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

단일 csv 파일로 내보내려면 다음을 사용하십시오.

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

@ wisty, @ Andy, 모든 파일에 각 행에 대한 제목이 있다고 가정합니다. 일부 행에는 다른 제목이 있습니다. 각 파일의 2 개 열에 대한 헤더가 없습니다. 하나의 병합하여 각 파일에 대해 열만 추가하는 방법.
Gathide

파일을 어디로 내보내나요?

@ dirtysocks45, 나는 이것을 더 명확하게 만들기 위해 대답을 변경했습니다.
scottlittle

정렬 추가 : Combined_csv = pd.concat ([pd.read_csv (f) for f in filenames], sort = False)
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()

12

바구니에있는 다른 코드 예제를 살펴 보겠습니다.

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와 그들이 내 대답이 유용하다고 생각하면 사람들이 감사를 공유하도록 상기시키는 것 (투표를 통해)의 차이점을 보지 못했습니다. 나는이 페이스 북 아니며, 나는 같은 사냥꾼 아니에요 알고 ...
Norfeldt

1
이전논의 되었으며 , 매번 허용되지 않는 것으로 간주 됩니다.
Andy

10

"병합"이 의미하는 바에 따라 다릅니다. 동일한 열이 있습니까? 헤더가 있습니까? 예를 들어, 모두 동일한 열이 있고 헤더가없는 경우 간단한 연결만으로도 충분합니다 (쓰기를 위해 대상 파일을 열고, 읽기 위해 각각을 여는 소스를 반복하고, 읽기 위해 열기 소스의 shutil.copyfileobj 를 사용 하여 쓰기 위해 열기 대상, 소스 닫기, 계속 반복- with명령문을 사용 하여 대신 닫기를 수행하십시오). 열이 같지만 헤더도 readline있는 경우 첫 번째 파일을 제외하고 각 소스 파일에이 파일 이 있어야합니다 . 첫 번째 파일을 열어서 대상으로 복사하기 전에 헤더 행을 건너 뜁니다.

CSV 파일이 모두 동일한 열을 가지고 있지 않다면 어떤 의미로 "병합"하는지 정의해야합니다 (예 : SQL JOIN? 또는 모두 동일한 수의 행이있는 경우 "수평"? 등). )-이 경우 당신이 의미하는 바를 추측하기가 어렵습니다.


각 파일에는 헤더가있는 두 개의 열이 있습니다. 연속적으로 두 개의 열이있는 단일 파일로 병합하고 싶습니다.
Chuck


3

실제로 제대로 작동하지 않기 때문에 위의 코드를 약간 변경했습니다.

다음과 같아야합니다 ...

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

디렉토리의 모든 파일을 결합하고 병합하는 것이 매우 쉽습니다.

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에서 작업하는 경우이를 수행 할 수 있습니다.

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


1

csv를 가져온 다음 목록으로 읽는 모든 CSV 파일을 반복 할 수 있습니다. 그런 다음 목록을 디스크에 다시 씁니다.

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

위의 내용은 오류 처리가없고 열려있는 파일을 닫지 않기 때문에 강력하지 않습니다. 이것은 개별 파일에 하나 이상의 CSV 데이터 행이 있는지 여부에 관계없이 작동합니다. 또한이 코드를 실행하지는 않았지만 무엇을해야하는지에 대한 아이디어를 제공 할 것입니다.


1

@Adders를 만들고 나중에 @varun에 의해 개선 된 솔루션에 대해 약간의 개선을 구현하여 전체 병합 된 CSV를 기본 헤더 만 남겨 둡니다.

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

친애하는!!!


1

내장 csv라이브러리 를 사용하기 만하면됩니다 . 이 솔루션은 다른 상위 투표 답변과 달리 일부 CSV 파일의 열 이름이나 헤더가 약간 다른 경우에도 작동합니다.

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)

병합 된 파일에는 header_keys파일에서 찾을 수있는 가능한 모든 열 ( ) 이 포함됩니다 . 파일에없는 열은 공백 / 빈 상태로 렌더링되지만 파일의 나머지 데이터는 유지됩니다.

노트 :

  • CSV 파일에 헤더가 없으면 작동하지 않습니다. 이 경우에도 csv라이브러리를 계속 사용할 수 있지만 DictReader& 를 사용하는 대신 DictWriter기본 reader& 으로 작업해야합니다.writer .
  • 콘텐츠 전체가 메모리 ( merged_rows목록) 에 저장되므로 대용량 데이터를 처리 할 때 문제가 발생할 수 있습니다 .

0

인코딩 문제가있는 사람들을 위해 @wisty가 python 3.x에서 작업한다고 말한 내용을 수정했으며 하드 코딩을 피하기 위해 os 모듈을 사용합니다.

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

다음은 스크립트입니다.

  • 합치 CSV의 이름은 파일 SH1.csvSH200.csv
  • 헤더 유지
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

python3에 대한 wisty의 답변 업데이트

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

2가 있다고 가정 해 봅시다. csv 과 같은 파일 .

csv1.csv :

id,name
1,Armin
2,Sven

csv2.csv :

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

결과가 다음 csv3.csv와 같기를 원합니다.

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

그런 다음 다음 스 니펫을 사용하여 수행 할 수 있습니다.

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)

루프를 사용하면 여러 파일에 대해 동일한 결과를 얻을 수 있습니다 (200 csv 파일).


0

파일에 순서대로 번호가 지정되지 않은 경우 아래의 번거 로움없는 접근 방식을 사용하십시오. Windows 시스템의 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

사용하기 쉬운 기능 :

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()
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.