合并来自csv文件的数据

时间:2016-01-14 17:23:59

标签: python csv python-3.x pandas

我有以下模式中具有相同列数(不同行数)的100个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+...

例如:

档案1:

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

文件2:

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

输出:

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

我真的很想知道如何解决这个问题......任何机构都可以给我一些建议吗?

非常感谢和最诚挚的问候, 儒略

编辑: 我要感谢' pepr'他非常详细的回答很多,但我想找到一个使用pandas的解决方案,如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的最后一行。我该怎么解决这个问题?我认为panda by group by panda可能是个选择,但我不明白如何使用它。

PS:残基是一个包含所有列标题的列表。

2 个答案:

答案 0 :(得分: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()提取两行元组 - 元素分配给row1row2。在循环内部,可以使用普通zip(),因为您将始终拥有文件中的行或fillvalue中的零。你总是得到第一行的一个元素和第二行的第二个元素。它们必须从string转换为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 :(得分: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*']