【问题标题】:Python CSV ComparisonPython CSV 比较
【发布时间】:2014-04-21 08:45:51
【问题描述】:

此脚本比较两个 csv 文件...有两列如果 sample1.csv 和 sample2.csv 有超过 2 列或 1 列,请帮我修改此脚本。

f1_in = open("sample1.csv","r")
next(f1_in,None)
f1_dict = {}
for line in f1_in:
  l = line.split(',')
  f1_dict[l[0]. strip()] = l[1]. strip() 
  l.sort()
f1_in.close()

f2_in = open("sample2.csv","r")
next(f2_in,None)
f2_dict = {}
for line in f2_in:
  l = line.split(',')
  f2_dict[l[0]. strip()] = l[1]. strip()
  l.sort()
f2_in.close()


f_same = open("same.txt","w")
f_different = open("different.txt","w")

for k1 in f1_dict.keys():
  if k1 in f2_dict.keys() \
      and f2_dict[k1] == f1_dict[k1]:
    f_same.write("{0}, {1}\n". format(str(k1)+" "+str(f1_dict[k1]),
                                    str(k1)+" "+str(f2_dict[k1])))

  elif not k1 in f2_dict.keys():
    f_different.write("{0}, {1}\n". format(str(k1)+" "+str(f1_dict[k1]),
                                           "------"))
  elif not f2_dict[k1] == f1_dict[k1]:
    f_different.write("{0}, {1}\n". format(str(k1)+" "+str(f1_dict[k1]),
                                           str(k1)+" "+str(f2_dict[k1])))

f_same.close()
f_different.close()

例如:如果我的源文件具有名称和薪水作为标题,其值为 A 20000 B 15000 C 10000 D 10000,而目标文件也具有名称和薪水的标题具有值 A 40000 D 10000 B 15000 C 10000 E 8000.. .my 输出应该是不同的行:A 20000 A 40000 D 10000 -----(目标中没有文件)-----(源中没有文件)E 8000 和常用行为 B 15000 B 15000,C 10000 C 10000

【问题讨论】:

  • 那么在这些情况下您有什么问题?您是否收到错误或意外输出?到目前为止,您尝试了哪些使代码更通用的方法?
  • Hy...jonrshape 如果我在源和目标中只有两列要比较,我得到它是正确的...如果有 1 列和超过 2 列也...只是采取只有两列用于比较...
  • 所以,再说一遍; 到目前为止,您尝试了什么?您认为哪些代码位与列数相关?您认为哪种数据结构适合处理任意数量的列?
  • 我对 python 还是很陌生,即使这段代码我只是从 stackoverflow 得到的......我猜从 f1_dict.keys() 中的 k1 开始进行比较的最后一部分:是变化的地方应该读取n列...
  • 我建议您花更多的精力来理解您现在拥有的代码。输入一些prints,弄清楚发生了什么,然后你就可以弄清楚如何修改它。这不是代码编写服务。

标签: python csv comparison


【解决方案1】:

如果您将列视为字典中的键/值对,则难怪不能将代码扩展到两列以上。

您必须将它们视为“集合中的元素”。我理解这就是为什么您不使用 csv 模块或 difflib 模块的原因:因为您不关心这些行在任一文件中是否以(几乎)相同的顺序出现,而是它们是否出现。

这是一个例子:

import itertools


def compare(first_filename, second_filename):
    lines1 = set()
    lines2 = set()
    with open(first_filename, 'r') as file1, \
            open(second_filename, 'r') as file2:
        for line1, line2 in itertools.izip_longest(file1, file2):
            if line1:
                lines1.add(line1)
            if line2:
                lines2.add(line2)
    print "Different lines"
    for line in lines1 ^ lines2:
        print line,
    print "---"
    print "Common lines"
    for line in lines1 & lines2:
        print line,

请注意,此代码将发现两个文件上的差异,而不仅仅是 f1 上存在的东西,而不是 f2 上的东西,就像您的示例一样。但是,它无法判断差异来自何处(因为这似乎不是问题的要求)。

检查它是否有效

In [40]: !cat sample1.csv
bacon, eggs, mortar
whatever, however, whenever
spam, spam, spam

In [41]: !cat sample2.csv
guido, van, rossum
spam, spam, spam

In [42]: compare("sample1.csv", "sample2.csv")
Different lines
whatever, however, whenever
guido, van, rossum
bacon, eggs, mortar
---
Common lines
spam, spam, spam

【讨论】:

  • logc...我们应该在哪里输入文件名?
  • @user3514648 :我不确定我是否理解您的问题。如果你要比较的CSV文件分别叫做“sample1.csv”和“sample2.csv”,那么在同目录下打开一个Python控制台,将上面的sn-p剪切粘贴到控制台,然后写compare("sample1.csv", "sample2.csv") .另一种方法是:在模块example.py 中写入sn-p 和前面提到的行不带缩进,然后在文件所在的同一目录中运行python example.py
  • thanks...itz 工作,但不是我想要的确切方式,例如:如果我的源文件有 Name 和 Salary 作为标题,值为 A 20000 B 15000 C 10000 D 10000 和目标文件也有Name and Salary 的标题具有值 A 40000 D 10000 B 15000 C 10000 E 8000...我的输出应该是不同的行:A 20000 A 40000 D 10000 -----(目标中没有文件)-----(源代码中没有文件)E 8000 和常用行为 B 15000 B 15000、C 10000 C 10000
  • @user3514648:我认为你应该在问题中写下这些信息。这将帮助除我之外的其他人来帮助你。
  • 对不起...你能帮我解散吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-05-28
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多