Ребята, у меня есть 200 отдельных файлов csv, названных из SH (1), на SH (200). Я хочу объединить их в один файл csv. Как я могу это сделать?
Как объединить 200 файлов csv в Python
Ответ 1
Как сказал 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()
Ответ 2
Почему вы не можете просто sed 1d sh*.csv > merged.csv
?
Иногда вам даже не нужно использовать python!
Ответ 3
Используйте fooobar.com/questions/107520/..., чтобы создать список файлов 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 )
Ответ 4
fout=open("out.csv","a")
for num in range(1,201):
for line in open("sh"+str(num)+".csv"):
fout.write(line)
fout.close()
Ответ 5
Я просто проведу другой пример кода в корзине
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)
Ответ 6
Это зависит от того, что вы подразумеваете под "слиянием" - есть ли у них одинаковые столбцы? У них есть заголовки? Например, если все они имеют одинаковые столбцы и нет заголовков, достаточно простой конкатенации (откройте файл назначения для записи, зациклитесь на источниках, открывающих каждый для чтения, используйте shutil.copyfileobj из открытого источника для чтения в открытое для записи место, закройте источник, продолжайте цикл - используйте оператор with
, чтобы сделать закрытие от вашего имени). Если они имеют одинаковые столбцы, но также и заголовки, вам понадобится readline
для каждого исходного файла, кроме первого, после того, как вы откроете его для чтения, прежде чем копировать его в место назначения, чтобы пропустить строку заголовков.
Если файлы CSV не все имеют одинаковые столбцы, вам нужно определить, в каком смысле вы их "слияете" (например, SQL JOIN? или "по горизонтали", если все они имеют одинаковое количество строк? и т.д.) - нам трудно угадать, что вы имеете в виду в этом случае.
Ответ 7
Если объединенный CSV будет использоваться в Python, просто используйте glob
, чтобы получить список файлов, которые нужно передать fileinput.input()
с помощью аргумента files
, затем используйте csv
, чтобы прочитать все за один раз.
Ответ 8
Небольшое изменение в коде выше, так как оно действительно не работает правильно.
Это должно быть следующим образом:
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)
Ответ 9
Довольно просто объединить все файлы в каталоге и объединить их
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)
Ответ 10
Если вы работаете на Linux/Mac, вы можете сделать это.
from subprocess import call
script="cat *.csv>merge.csv"
call(script,shell=True)
Ответ 11
Вы можете импортировать 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 в них. Также я не запускал этот код, но он должен дать вам представление о том, что делать.
Ответ 12
Я изменил то, что @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()
Ответ 13
Вот скрипт:
- Конкатенация файлов 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())
Ответ 14
Обновление мудрого ответа для 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()
Ответ 15
Допустим, у вас есть 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 файлов).
Ответ 16
Если файлы не пронумерованы по порядку, используйте беспрепятственный подход ниже: 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)
Ответ 17
ИЛИ, вы могли бы просто сделать
cat sh*.csv > merged.csv
Ответ 18
Простая в использовании функция:
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, does not 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)