通过在存在的相同列条目中添加值来合并 csv 文件
Merge csv files by adding the values in same column entries when present
我有一些 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
我尝试了 join 和 cat,但这些将它们堆叠在一起。知道如何将它们加在一起吗?
多个文件的解决方案
这是一个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
读取一个输入文件和 returns 一个像这样的字典:
{'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 space 并将第二列中的字符串转换为整数。
使用此函数读取两个输入文件后:
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
returns 如果名称在字典中则为值。否则,它将 returns 作为第二个参数给出的 0
。
最后,我们逐行写下这个结果:
fobj.write('{},{}\n'.format(name, val))
我有一些 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
我尝试了 join 和 cat,但这些将它们堆叠在一起。知道如何将它们加在一起吗?
多个文件的解决方案
这是一个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
读取一个输入文件和 returns 一个像这样的字典:
{'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 space 并将第二列中的字符串转换为整数。
使用此函数读取两个输入文件后:
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
returns 如果名称在字典中则为值。否则,它将 returns 作为第二个参数给出的 0
。
最后,我们逐行写下这个结果:
fobj.write('{},{}\n'.format(name, val))