2015-12-14 4 views
2

Я распределил информацию по нескольким большим CSV-файлам. Я хочу, чтобы объединить все файлы в один новый файл, например в первом ряду от первого файла в сочетании с первой строки из другого файла и т.д.Python объединяет строки из разных файлов в один файл данных

file1.csv 

A,B 
A,C 
A,D 

file2.csv 

F,G 
H,I 
J,K 

ожидаемый результат:

output.csv 

A,B,F,G 
A,C,H,I 
A,D,J,K 

поэтому рассмотрим, что у меня есть массив ['file1.csv', 'file2.csv', ...] Как это сделать?

Я попытался загрузить каждый файл в память и объединить на np.column_stack, но мои файлы слишком велики, чтобы вписаться в память.

+1

Я не буду писать ваш код для вас, но я предлагаю повторять его по строкам и использовать 'str.join (',', (file1line, file2line))' для создания вашей выходной строки. Возможно, вам также придется отключить новые строки из строк ввода. – SiHa

+0

@SiHa. Спасибо за ваш комментарий. Однако моя проблема в том, что у меня есть 50 файлов. как я могу перебирать все файлы параллельно? – belas

+0

50 файлов несколько сложнее :) См. Ответ ниже. – SiHa

ответ

2

Не очень-код, но это должно работать.

Я не использую with(open'filename','r') as myfile для входов. Он может немного запутаться в 50 файлах, поэтому они открыты и закрыты явно.

Он открывает каждый файл и помещает его в список. Первый дескриптор берется как главный файл, затем мы последовательно перебираем его по очереди, каждый раз, читая одну строку из всех остальных открытых файлов и присоединяя их к ',', выводим их в выходной файл.

Обратите внимание, что если в других файлах больше строк, они не будут включены. Если у кого-то меньше строк, это вызовет исключение. Я оставлю это вам, чтобы грамотно разобраться с этими ситуациями.

Заметим также, что вы можете использовать glob для создания filelist если имена следовать логическому шаблону (благодаря Н. Wouda ниже)

filelist = ['book1.csv','book2.csv','book3.csv','book4.csv'] 
openfiles = [] 
for filename in filelist: 
    openfiles.append(open(filename,'rb')) 

# Use first file in the list as the master 
# All files must have same number of lines (or greater) 
masterfile = openfiles.pop(0) 

with (open('output.csv','w')) as outputfile: 
    for line in masterfile: 
     outputlist = [line.strip()] 
     for openfile in openfiles: 
      outputlist.append(openfile.readline().strip()) 
     outputfile.write(str.join(',', outputlist)+'\n') 

masterfile.close() 
for openfile in openfiles: 
    openfile.close() 

Входные файлы

a b c d e f 
1 2 3 4 5 6 
7 8 9 10 11 12 
13 14 15 16 17 18 

Выход

a b c d e f a b c d e f a b c d e f a b c d e f 
1 2 3 4 5 6 1 2 3 4 5 6 1 2 3 4 5 6 1 2 3 4 5 6 
7 8 9 10 11 12 7 8 9 10 11 12 7 8 9 10 11 12 7 8 9 10 11 12 
13 14 15 16 17 18 13 14 15 16 17 18 13 14 15 16 17 18 13 14 15 16 17 18 
+2

Обратите внимание, что вы можете не вручную указывать все файлы в списке файлов, если они разделяют логическую структуру (например, 'file1.csv',' file2.csv' и т. Д.). Просто сделайте это: 'from glob import glob', а затем получите такие файлы: filelist = glob ('file * .csv')' –

+0

@ N.Wouda: Спасибо, добавил ваше предложение к ответу. – SiHa

1

Вместо полного чтения файлов в память вы можете перебирать их по строкам.

from itertools import izip # like zip but gives us an iterator 

with open('file1.csv') as f1, open('file2.csv') as f2, open('output.csv', 'w') as out: 
    for f1line, f2line in izip(f1, f2): 
     out.write('{},{}'.format(f1line.strip(), f2line)) 

Демо:

$ cat file1.csv 
A,B 
A,C 
A,D 
$ cat file2.csv 
F,G 
H,I 
J,K 
$ python2.7 merge.py 
$ cat output.csv 
A,B,F,G 
A,C,H,I 
A,D,J,K 
+0

Для полноты, в python 3 встроенный zip также создает итератор. – Ogaday

Смежные вопросы