【问题标题】:Trying to compare two csv files and write differences as output尝试比较两个 csv 文件并将差异写入输出
【发布时间】:2017-01-31 21:09:47
【问题描述】:

我正在开发一个脚本,它获取 2 个 csv 文件之间的差异,并制作一个新的 csv 文件作为输出,但只有当两个输入文件之间的相同 2 行(指行号)包含不同的数据时,例如文件 1 中的第 3 行有“mike”、“basketball player”,文件 2 中的第 3 行有“mike”、“baseball player”。输出 csv 会抓取这些打印它们并将它们写入 csv。它有效,但存在一些问题(我知道这个问题之前也被问过好几次,但其他人对我的做法不同,而且由于我对编程还很陌生,所以我不太了解他们的代码)。

新 csv 文件中的输出在每个单元格中都有输出的每个字母(见下图),我相信这与第 37 行的分隔符/引号字符/引号有关。我希望它们在自己的单元格中没有任何句号、多个空格、逗号或“|”。

另一个问题是它需要很长时间才能运行。我正在处理多达 50,000 行的数据集,运行可能需要一个多小时。为什么会这样?有什么建议可以加快速度?也许在 for 循环之外放一些东西?我之前确实尝试过 difflib 方法,但我只能打印整个“input_file1”,但不能将该文件与另一个文件进行比较。

# aim of script is to compare csv files and output difference as a new csv

# import necessary libraries
import csv

# File1 = open(raw_input("path:"),"r") #filename, mode
# File2 = open(raw_input("path:"),"r") #filename, mode

# selects the 2 input files to be compared
input_file1 = "G:/savestuffhereqwerty/electorate_meshblocks/teststuff/Book1.csv"
input_file2 = "G:/savestuffhereqwerty/electorate_meshblocks/teststuff/Book2.csv"
# creates the blank output csv file
output_path = "G:/savestuffhereqwerty/electorate_meshblocks/outputs/output2.csv"
a = open(input_file1, "r")
output_file = open(output_path,"w")
output_file.close()
count = 0

with open(input_file1) as fp1:


    for row_number1, row_value1 in enumerate(fp1):
        if row_number1 == count:
            print "got to 1st point"
            value1 = row_value1

            with open(input_file2) as fp2:
                for row_number2, row_value2 in enumerate(fp2):
                    if row_number2 == count:
                        print "got to 2nd point"
                        value2 = row_value2

                        if value1 == value2:
                            print value1, value2
                        else:
                            print value1, value2
                            with open(output_path, 'wb') as f:
                                writer = csv.writer(f, delimiter=',', quotechar='|', quoting=csv.QUOTE_MINIMAL)
                                # testing to see if the code writes text to the csv
                                writer.writerow(["test1"])
                                writer.writerow(["test2", "test3", "test4"])
                                writer.writerows([value1, value2])
                                print "code reached writing stage"
        count += 1
        print count
print "done"
# replace(",",".")

【问题讨论】:

  • 您有一个超过 50000 行的嵌套循环。这就是长运行时间的来源。您不必将 a 中的每一行与 b 中的每一行进行比较!
  • 是因为我在 for 循环中有一个 for 循环吗?我不知道如何在第一个 for 循环中引用 input_file2 ..

标签: python csv compare difference


【解决方案1】:

由于您要逐行比较这两个文件,您应该在第一个文件中的每一行循环第二个文件。您可以简单地 zip 两个 csv 阅读器并过滤行:

input_file1 = "foo"
input_file2 = "bar"
output_path = "baz"

with open(input_file1) as fin1:
  with open(input_file2) as fin2:
    read1 = csv.reader(fin1)
    read2 = csv.reader(fin2)
    diff_rows = (row1 for row1, row2 in zip(read1, read2) if row1 != row2)
    with open(output_path, 'w') as fout:
      writer = csv.writer(fout)
      writer.writerows(diff_rows)

此解决方案假定两个文件具有相同的行数。

【讨论】:

  • 非常感谢。我的输出给了我不同的行,但对于 input_file1。我试图了解您所写的内容,我该如何更改,以便我的输出显示 input_file2 的不同行? @schwobaseggl
  • @Crow132 你现在可能已经发现了。将row1 for ... 替换为row2 for ...。这条线是conditional generator expression。这是 Python 中最方便的功能之一。我认为语法是不言自明的;-)
猜你喜欢
  • 2014-06-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-07-13
  • 2013-06-17
  • 2016-12-24
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多