Как объединить 200 CSV-файлов в Python - PullRequest
65 голосов
/ 25 марта 2010

Ребята, у меня здесь есть 200 отдельных CSV-файлов с именами от SH (1) до SH (200).Я хочу объединить их в один CSV-файл.Как я могу это сделать?

Ответы [ 16 ]

1 голос
/ 25 марта 2010

Вы можете импортировать 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.Также я не запускал этот код, но он должен дать вам представление о том, что делать.

0 голосов
/ 11 февраля 2019

Если файлы не пронумерованы по порядку, воспользуйтесь удобным подходом ниже: Python 3.6 на машине windows:

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 голосов
/ 14 декабря 2018

Допустим, у вас есть 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 голосов
/ 02 мая 2018

Обновление ответа wisty для python3

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 голосов
/ 02 февраля 2018

Вот скрипт:

  • Объединение CSV-файлов с именами от SH1.csv до SH200.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 голосов
/ 28 сентября 2017

Я изменил то, что @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()
...