2016-01-14 3 views
0

у меня есть 100 файлов CSV с одинаковым числом столбцов (разным количеством строк) в следующей схеме:Объединить данные из CSV файлов

Файлы 1:

A1,B1,C1 
A2,B2,C2 
A3,B3,C3 
A4,B4,C4 

Файл 2:

*A1*,*B1*,*C1* 
*A2*,*B2*,*C2* 
*A3*,*B3*,*C3* 

Файл ...

Выход:

A1+*A1*+...,B1+*B1*+...,C1+*C1*+... 
A2+*A2*+...,B2+*B2*+...,C2+*C2*+... 
A3+*A3*+...,B3+*B3*+...,C3+*C3*+... 
A4+...  ,B4+...  ,C4+... 

Например:

Files 1:

1,0,0 
1,0,1 
1,0,0 
0,1,0 

Files 2:

1,1,0 
1,1,1 
0,1,0 

Выход:

2,1,0 
2,1,2 
1,1,0 
0,1,0 

Я действительно ломать голову о том, как решить это ... Может ли любой b Ой, дайте мне совет?

Спасибо и наилучшие пожелания, Джулиан

Edit: Я хочу поблагодарить «pepr» много для его очень подробно ответа, но я хотел бы найти решение с помощью панд, как было предложено «furas» , Я нашел способ, чтобы создать переменные для всех моих файлов, как это:

dic={} 
for i in range(14253,14352): 
     try: 
       dic['df_{0}'.format(i)]=pandas.read_csv('output_'+str(i)+'.csv') 
     except: 
       pass 

но если я пытаюсь предложенный

df1['column_A'] += df2['column_*A*'] 

Потому что у меня есть 100 файлов в моем случае она должна была бы быть что-то вроде

for residue in residues: 
     for number in range(14254,14255): 
       df=dic['df_14253'][residue] 
       df+=dic['df_'+str(number)][residue] 

у меня есть проблема, что мои файлы имеют разное количество строк и не только суммируются до последней строки df1. Как я могу это решить? Я думаю, что groupby.sum by panda может быть вариантом, но я не понимаю, как его использовать.

PS: Остатки - это список, содержащий все заголовки столбцов.

+0

Я надеваю я не знаю, как начать ... Я думал, что, возможно, я мог бы обрабатывать его как матрицу, а затем использовать некоторую библиотеку numpy. Чтобы читать каждый файл по строкам, а затем добавление данных кажется слишком сложным/unpythonish для меня ... Я надеялся, что для модуля csv будет такая возможность. – Julian

ответ

2

Раствор со стандартными модулями могут быть такими:

#!python3 

import csv 
import itertools 

fname1 = 'file1.csv' 
fname2 = 'file2.csv' 
fname_out = 'output.csv' 
with open(fname1, newline='') as f1,\ 
    open(fname2, newline='') as f2,\ 
    open(fname_out, 'w', newline='') as fout: 

    reader1 = csv.reader(f1) 
    reader2 = csv.reader(f2) 
    writer = csv.writer(fout) 

    for row1, row2 in itertools.zip_longest(reader1, reader2, fillvalue=['0', '0', '0']): 
     row_out = [int(a) + int(b) for a, b in zip(row1, row2)] 
     writer.writerow(row_out) 

itertools реализует zip_longest(), который похож на встроенный zip(); однако он может обрабатывать последовательности разной длины. Здесь третий параметр fillvalue - это быстрый взломать 3 столбца.На самом деле он может быть установлен в [0, 0, 0] (то есть целые числа вместо строк), потому что int(0) также равен нулю.

Каждый zip_longest() извлекает кортеж из двух рядов - элементы присваиваются row1 и row2. Внутри цикла можно использовать обычный zip(), так как вы всегда будете иметь строку из файла или fillvalue с нулями. Вы всегда получаете tupple с одним элементом из первой строки и вторым элементом из второй строки. Они должны быть преобразованы из строки в int, а затем они добавляются для формирования одного элемента в row_out.

Лучшее решение цикла, которое не полагается на фиксированное количество столбцов, использует значение None как fillvalue. Если одна из строк равна None, тогда она устанавливается в список с тем же числом нулей, которое имеет другую строку. Это означает, что вы можете даже строки разной длины в одном файле (но должны быть такими же, я и файлы,. Противоположность также может быть легко решена с помощью zip_longest() также в теле цикла

for row1, row2 in itertools.zip_longest(reader1, reader2): 

     if row1 is None: 
      row1 = [0] * len(row2) 
     elif row2 is None:  
      row2 = [0] * len(row1) 

     row_out = [int(a) + int(b) for a, b in zip(row1, row2)] 
     writer.writerow(row_out) 
1

Использование pandas.

Он может читать CSV-файлы и может добавлять два столбца.

import pandas as pd 

df1 = pd.read_csv(filename_1) 
df2 = pd.read_csv(filename_2) 

df1['column_A'] += df2['column_*A*'] 
Смежные вопросы