【问题标题】:Merge csv files by adding the values in same column entries when present通过在存在的相同列条目中添加值来合并 csv 文件
【发布时间】:2016-03-24 03:27:09
【问题描述】:

我有许多 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 文件,如下面的示例输出所示。

输出.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

我尝试了 join 和 cat ,但它们将它们堆叠在一起。知道如何将它们加在一起吗?

【问题讨论】:

  • 到目前为止你尝试了什么?
  • 我试过加入和猫。

标签: csv merge add


【解决方案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}

从这对中创建一个字典,从名称中去除多余的空格并将第二列中的字符串转换为整数。

使用此函数读取两个输入文件后:

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))

【讨论】:

  • 不,因为我要合并 6 到 9 个文件
  • @user3767953 添加了多个文件的版本。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-03-09
  • 1970-01-01
  • 1970-01-01
  • 2019-07-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多