【问题标题】:Merging two CSV files using Python使用 Python 合并两个 CSV 文件
【发布时间】:2013-04-22 08:42:26
【问题描述】:

好的,我已经阅读了 Stack Overflow 上的几个主题。我认为这对我来说相当容易,但我发现我仍然没有很好地掌握 Python。我尝试了位于How to combine 2 csv files with common column value, but both files have different number of lines 的示例,这很有帮助,但我仍然没有得到我希望达到的结果。

基本上我有 2 个 csv 文件,它们有一个共同的第一列。我想合并2。即

filea.csv

标题,阶段,一月,二月 该死,3.001,0.421,0.532 好的,2.829,1.036,0.751 三、1.115、1.146、2.921

fileb.csv

标题,三月,四月,五月,六月, 该死,0.631,1.321,0.951,1.751 好的,1.001,0.247,2.456,0.3216 三,0.285,1.283,0.924,956

output.csv(不是我得到的,而是我想要的)

标题,阶段,1 月,2 月,3 月,4 月,5 月,6 月 该死,3.001,0.421,0.532,0.631,1.321,0.951,1.751 好的,2.829,1.036,0.751,1.001,0.247,2.456,0.3216 三、1.115、1.146、2.921、0.285、1.283、0.924、956

output.csv(我实际得到的输出)

标题,二月,五月 好的,0.751,2.456 三、2.921、0.924 该死,0.532,0.951

我正在尝试的代码:

'''
testing merging of 2 csv files
'''
import csv
import array
import os

with open('Z:\\Desktop\\test\\filea.csv') as f:
    r = csv.reader(f, delimiter=',')
    dict1 = {row[0]: row[3] for row in r}

with open('Z:\\Desktop\\test\\fileb.csv') as f:
    r = csv.reader(f, delimiter=',')
    #dict2 = {row[0]: row[3] for row in r}
    dict2 = {row[0:3] for row in r}

print str(dict1)
print str(dict2)

keys = set(dict1.keys() + dict2.keys())
with open('Z:\\Desktop\\test\\output.csv', 'wb') as f:
    w = csv.writer(f, delimiter=',')
    w.writerows([[key, dict1.get(key, "''"), dict2.get(key, "''")] for key in keys])

非常感谢任何帮助。

【问题讨论】:

  • 你能用更简单的方式描述你想要什么吗?也许会说:我想要合并月份列,其余列来自 fileX

标签: python csv dictionary merge key


【解决方案1】:

当我处理csv 文件时,我经常使用pandas 库。它使这样的事情变得非常容易。例如:

import pandas as pd

a = pd.read_csv("filea.csv")
b = pd.read_csv("fileb.csv")
b = b.dropna(axis=1)
merged = a.merge(b, on='title')
merged.to_csv("output.csv", index=False)

下面是一些解释。首先,我们读入 csv 文件:

>>> a = pd.read_csv("filea.csv")
>>> b = pd.read_csv("fileb.csv")
>>> a
   title  stage    jan    feb
0   darn  3.001  0.421  0.532
1     ok  2.829  1.036  0.751
2  three  1.115  1.146  2.921
>>> b
   title    mar    apr    may       jun  Unnamed: 5
0   darn  0.631  1.321  0.951    1.7510         NaN
1     ok  1.001  0.247  2.456    0.3216         NaN
2  three  0.285  1.283  0.924  956.0000         NaN

我们看到有一个额外的数据列(请注意,fileb.csv 的第一行 -- title,mar,apr,may,jun, -- 末尾有一个额外的逗号)。我们可以很容易地摆脱它:

>>> b = b.dropna(axis=1)
>>> b
   title    mar    apr    may       jun
0   darn  0.631  1.321  0.951    1.7510
1     ok  1.001  0.247  2.456    0.3216
2  three  0.285  1.283  0.924  956.0000

现在我们可以在标题栏合并ab

>>> merged = a.merge(b, on='title')
>>> merged
   title  stage    jan    feb    mar    apr    may       jun
0   darn  3.001  0.421  0.532  0.631  1.321  0.951    1.7510
1     ok  2.829  1.036  0.751  1.001  0.247  2.456    0.3216
2  three  1.115  1.146  2.921  0.285  1.283  0.924  956.0000

最后写出来:

>>> merged.to_csv("output.csv", index=False)

制作:

title,stage,jan,feb,mar,apr,may,jun
darn,3.001,0.421,0.532,0.631,1.321,0.951,1.751
ok,2.829,1.036,0.751,1.001,0.247,2.456,0.3216
three,1.115,1.146,2.921,0.285,1.283,0.924,956.0

【讨论】:

  • 如何根据不同的名称列进行 .merge ?例如。像 A 列上的 aTable 合并 B 列上的 bTable 。
  • @JorgeVidinha:如果你有一个新问题,请打开一个新问题——如果你把它作为对一个已有一年的问题的评论提出来,没有人会看到它。
  • 优雅的解决方案,即使是 4 年后。但是,请注意不使用how="all".dropna() 方法;否则,如果任何单元格为空,它可能会删除列。
  • 对于非常大的 csv 文件是否有更好的方法? (以百万行为规模。)
  • 很好的答案 DSM 如何将文件保存在保存脚本的其他位置?
【解决方案2】:

您需要将所有额外行存储在字典中的文件中,而不仅仅是其中一个:

dict1 = {row[0]: row[1:] for row in r}
...
dict2 = {row[0]: row[1:] for row in r}

然后,由于字典中的值是列表,您只需将列表连接在一起即可:

w.writerows([[key] + dict1.get(key, []) + dict2.get(key, []) for key in keys])

【讨论】:

    猜你喜欢
    • 2020-11-22
    • 2020-08-22
    • 2020-03-18
    • 2012-08-12
    • 2019-02-22
    • 2019-03-27
    • 1970-01-01
    • 2019-12-21
    • 1970-01-01
    相关资源
    最近更新 更多