ProgramingTip

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

bestdevel 2020. 10. 25. 12:42
반응형

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


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


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

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

사용할 수 없습니다.


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

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

바구니에있는 다른 코드를 사용한 보겠습니다.

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)

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

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


병합 된 CSV가 파이썬 사용되는에서 경우를 사용하여 인수 통해 전달할 파일 목록을 가져온 다음 모듈을 사용하여 한 번에 모두 읽습니다.globfileinput.input()filescsv


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

다음과 소비 야합니다 ...

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)

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

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)

linux / mac에서 작업하는 경우를 수행 할 수 있습니다.

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


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 데이터 행이 있는지 여부에 관계없이 작동합니다. 또한이 코드를 실행하고 무엇을 해야하는지에 대한 아이디어를 제공 할 것입니다.


인코딩 문제가있는 사람들을 위해 @wisty가 사용하기 위해 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()

다음은 펼쳐입니다.

  • 합치 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())

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

다음 csv과 같은 2 개의 파일 이 존재 가정 해 보겠습니다 .

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 파일).


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

아니면 그냥 할 수 있습니다

cat sh*.csv > merged.csv

사용하기 쉬운 기능 :

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)

참고 URL : https://stackoverflow.com/questions/2512386/how-to-merge-200-csv-files-in-python

반응형