通过在存在时添加相同列条目中的值来合并csv文件

时间:2015-12-17 15:33:38

标签: csv merge add

我有很多csv文件。下面显示了两个示例文件。

input1.csv

Actinocyclus actinochilus,7
Asterionella formosa,4
Aulacodiscus orientalis,1
Aulacoseira granulata,3
Chaetoceros radicans,1
Corethron hystrix,6
Coscinodiscaceae 1 
Dactyliosolen fragilissimus,32
Diadesmis gallica,1
Diatoma hyemalis 1
Synedropsis hyperboreoides,4
Trigonium formosum,4
Urosolenia eriensis,2

input2.csv

Actinocyclus actinochilus,55
Asterionella formosa,3
Aulacoseira granulata,5
Chaetoceros radicans,7
Dactyliosolen fragilissimus,5
Diatoma hyemalis,1
Stephanopyxis turris,1
Striatella unipunctata,1
Synedropsis hyperboreoides,28
Trigonium formosum,3
Urosolenia eriensis,2

我想通过在第一列中添加第二列来合并这些csv文件,如下面的示例输出中所示。

output.csv

Actinocyclus actinochilus,62
Asterionella formosa,7
Aulacodiscus orientalis,1
Aulacoseira granulata,8
Chaetoceros radicans,8
Corethron hystrix,6
Coscinodiscaceae, 1 
Dactyliosolen fragilissimus,37
Diadesmis gallica,1
Diatoma hyemalis,2
Stephanopyxis turris,1
Striatella unipunctata,1
Synedropsis hyperboreoides,32
Trigonium formosum,7
Urosolenia eriensis,4

我试过加入和猫,但这些把它们叠在一起。任何想法如何将它们加在一起?

1 个答案:

答案 0 :(得分:1)

多个文件的解决方案

这是一个Python 3解决方案。如果您需要使用它来使用Python 2,请将此行names = inp.keys() | data.keys()更改为names = inp.viewkeys() | data.viewkeys()

# get this list of file names form somewhere like `glob`
file_names = ['input1.csv', 'input2.csv', 'input3.csv', 'input4.csv']

def file_to_dict(file_name):
    """Read a two-column csv file into a dict with first column as key
       and an integer value from the second column. 
    """
    with open(file_name) as fobj:
        pairs = (line.split(',') for line in fobj if line.strip())
        return {k.strip(): int(v) for k, v in pairs}

def merge(data, file_name):
    """Merge input file with dict `data` adding the numerical values.
    """
    inp = file_to_dict(file_name)
    names = inp.keys() | data.keys()
    for name in names:
        data[name] = data.get(name, 0) + inp.get(name, 0)
    return data

data = {}
for file_name in file_names:
    merge(data, file_name)

with open('output.csv', 'w') as fobj:
    for name, val in sorted(data.items()):
        fobj.write('{},{}\n'.format(name, val))

两个文件的解决方案

这会产生所需的输出:

def file_to_dict(file_name):
    """Read a two-column csv file into a dict with first column as key
       and an integer value from the second column. 
    """
    with open(file_name) as fobj:
        pairs = (line.split(',') for line in fobj if line.strip())
        return {k.strip(): int(v) for k, v in pairs}

inp1 = file_to_dict('input1.csv')
inp2 = file_to_dict('input2.csv')
names = sorted(inp1.keys() | inp2.keys())

with open('output.csv', 'w') as fobj:
    for name in names:
        val = inp1.get(name, 0) + inp2.get(name, 0)
        fobj.write('{},{}\n'.format(name, val))

说明

函数file_to_dict读取一个输入文件并返回如下字典:

{'Actinocyclus actinochilus': 7,
 'Asterionella formosa': 4,
  ...

下一步:

pairs = (line.split(',') for line in fobj if line.strip())

pairs包含一个生成器表达式,表示所有名称 - 值对作为字符串。然后:

{k.strip(): int(v) for k, v in pairs}

从这些对中创建一个字典,从名称中去除额外的whits空间,并将第二列中的字符串转换为整数。

使用此功能读取两个输入文件后:

names = sorted(inp1.keys() | inp2.keys())

使用两个输入中的名称的并集,即input1和input2中出现的所有名称,并按字母顺序对它们进行排序。

输出文件需要在写入模式下打开:

with open('output.csv', 'w') as fobj:
每个名称

    for name in names:

我们从输入词典中检索值:

val = inp1.get(name, 0) + inp2.get(name, 0)

如果名称在字典中,方法get将返回值。否则,它返回作为第二个参数给出的0

最后,我们逐行写出这个结果:

fobj.write('{},{}\n'.format(name, val))