Python逐行比较两个CSV文件

时间:2014-07-03 14:50:46

标签: python csv diff with-statement

我目前有一个脚本版本,它通过将两个csv文件一个接一个地读入列表/集来比较两个csv文件。 但是,csvs目前对于内存来说太大了,所以我想逐行迭代并打印出不同的行。

我不能做两个csvreaders循环,因为内部循环将读取整个文件,而外部循环将在第一行

我宁愿这样做而不是差异所以我可以在线条不匹配时打印出额外的信息以找出原因

编辑:到目前为止我做了类似的事情,但是csvs太大而无法一次加载到列表中

def readFile(filename,columns):
mylist=[]
    with open(filename,'rb') as f:
                reader = csv.reader(f)
                for line in reader:
                    mylist.append(tuple(line[i] for i in columns))
    return mylist

mylist1=readFile(filename1,columns)
mylist2=readFile(filename2,columns)
diff1=diff(mylist1,mylist2)
diff2=diff(mylist2,mylist2)

6 个答案:

答案 0 :(得分:3)

假设文件具有相同的行数,并且您只查找行内差异(即,将第一个文件中的第1行与第二个文件中的第1行进行比较,等等)这应该有效:

with open(filename1, 'rb') as f1, open(filename2, 'rb') as f2

  rdr1 = CsvReader(f1)
  rdr2 = CsvReader(f2)

  for file1_line in rdr1:

     file2_line = rdr2.next()

     # Perform your comparison between file1_line and file2_line here
     # and print differences, or accumulate only the differences in a 
     # results list.

答案 1 :(得分:1)

你可以试试这段代码。给你一组所有匹配的值。

import csv

result_path   = 'result_check.csv'
result_file = open(result_path,'r')
result_reader = csv.reader(result_file)

f1 = {}
for rows in result_reader:
    f1[rows[0]] = rows[1]


forest_path = 'pandababy3.csv'
forest_file = open(forest_path, 'r')
forest_reader = csv.reader(forest_file)

f2 = {}
for rows in forest_reader:
    f2[rows[0]] = rows[1]

x = len(set(f1.items()).intersection(set(f2.items())))

print(x)

编辑: 我正在使用行[1],因为我的文件有列标题。任何人使用此代码比较文件,没有列标题,请使用rows [0]。

答案 2 :(得分:0)

我想到了一种逐行读取文件的方法,并应用md5sum / SHA1和,然后比较这些值。如果空格或任何其他字符无关紧要,则在应用校验和之前删除它们

答案 3 :(得分:0)

itertools.izip()优雅地解决了这个问题:

import csv
import itertools

reader1 = csv.reader(filename1)
reader2 = csv.reader(filename2)

for lhs, rhs in itertools.izip(reader1, reader2):
    if lhs != rhs:
        print "difference:", lhs, rhs

答案 4 :(得分:0)

您可以使用' awk'轻松完成此操作。如果你使用的是Linux机器。

paste <(awk -F, '{ print $1;next } file1.csv ) <(awk -F, '{print $1;next } file2.csv) | awk '{ if ($1==$2) print "match" ; else print "mismatch" }'

$ 1表示第一个字段,$ 2秒表示依此类推。 $ 0表示整行。

说明:

这里,file1.csv的每一行中的字段1由第一个awk命令打印; file2.csv的每一行中的字段1由第二个awk命令打印。这些命令的输出使用粘贴命令并排打印。现在这是另一个awk命令,其中$ 1是file1.csv中的field1,$ 2是file2.csv中的第一个字段。然后将这两者进行比较,并打印出结果。

如果您想打印行号,可以使用&#34;打印NR&#34;,其中NR是记录号。

同样,你可以使用$ 2 $ 3来比较所有字段,依此类推

您还可以使用NR&lt; 10比较任意数量的行来打印十行中的第1行,如下所示:

awk -F, 'NR<=10{print $1}' file1.csv

在上面的命令中。

希望有所帮助。

答案 5 :(得分:0)

以下代码迭代每一行,并给出行号以及不同条目的位置和项目作为输出。如果行有很多项,假设使用逗号作为分隔符,则此解决方案 (python3) 很方便。

def compare_csv(file_1, file_2):

with open(file_1, 'r') as csv_1:
    with open(file_2, 'r') as csv_2:
        reader1 = csv.reader(csv_1, delimiter=',')
        reader2 = csv.reader(csv_2, delimiter=',')
        try:
            i_line = 0
            while True:
                row_1 = next(reader1)
                row_2 = next(reader2)
                i_line += 1
                if row_1 != row_2:
                    for k, item in enumerate(row_1):
                        if item != row_2[k]:
                            print(f"difference Line {i_line}: ")
                            print(f"item {k}: {row_1[k]}")
                            print(f"item {k}: {row_2[k]}")
        except StopIteration:
            print("line numbers differ!")
        finally:
            print(f"lines parsed = {i_line}")