Python逐行比较两个CSV文件

Python逐行比较两个CSV文件,python,csv,diff,with-statement,Python,Csv,Diff,With Statement,我目前有一个脚本版本,它通过将两个csv文件逐个读取到列表/集合中来比较两个csv文件。 然而,CSV目前对于内存来说太大了,所以我想逐行迭代并打印出不同的行 我不能对CSVReader执行两个循环,因为这样内部循环将读取整个文件,而外部循环将位于第一行 我宁愿这样做,而不是区分,这样当行不匹配时,我可以打印出额外的信息来找出原因 编辑:到目前为止,我做了类似的事情,但CSV太大,无法一次加载到列表中 def readFile(filename,columns): mylist=[] w

我目前有一个脚本版本,它通过将两个csv文件逐个读取到列表/集合中来比较两个csv文件。 然而,CSV目前对于内存来说太大了,所以我想逐行迭代并打印出不同的行

我不能对CSVReader执行两个循环,因为这样内部循环将读取整个文件,而外部循环将位于第一行

我宁愿这样做,而不是区分,这样当行不匹配时,我可以打印出额外的信息来找出原因

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

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)

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

我想到了一种逐行读取文件并应用md5sum/SHA1 sum的方法,然后比较这些值。如果空格或任何其他字符不重要,请在应用校验和之前删除它们,假设文件具有相同的行数,并且您只查找行内差异(即,将第一个文件中的行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进行比较,依此类推),类似这样的方法应该可以工作:

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.
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
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

你可以试试这个代码。为您提供一组所有匹配值

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],因为我的文件有列标题。任何使用此代码来比较没有列标题的文件的人,请使用行[0]。

您可以尝试此代码。为您提供一组所有匹配值

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],因为我的文件有列标题。任何使用此代码比较文件(无列标题)的人,请使用行[0]。

如果您使用的是Linux机器,则可以使用“awk”轻松完成此操作

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

paste如果您使用的是Linux机器,则可以使用“awk”轻松完成此操作

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

paste下面的代码在每行上迭代,并给出行号以及不同条目的位置和项目作为输出。假设使用逗号作为分隔符,则如果行中有许多项,则此解决方案(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}")

下面的代码迭代每一行,并给出行号以及不同条目的位置和项目作为输出。假设使用逗号作为分隔符,则如果行中有许多项,则此解决方案(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}")

那很好。到目前为止你试过什么?我举了一个很好的例子。到目前为止,您尝试了什么?我在上面给出了一个例子,这可能有效,但如果问题是我错误地输出了这些文件中的一个,我将无法分辨哪些列不匹配,区别是您可以有一个(校验和值,行数)列表,而不是仅校验和列表,那么您可以再次读取该文件(完成比较后)并保存不匹配的行以便稍后打印。这可能可行,但如果问题是我错误地输出了其中一个文件,我将无法分辨哪些列不匹配,区别是什么您可以有一个列表(校验和值、行数)不必只列出校验和,然后您可以再次读取文件(完成比较后),并保存不匹配的行以供以后打印。izip
itertools.izip是否内存效率更高?操作(大概是这样的)使用Python2,因此
zip
将耗尽两个迭代器,并将两个文件读入内存。为了避免这种情况,我们需要使用
itertools.izip
这里的实际读取发生在哪里。它是一次读取整个文件吗?@user3752900文件读取将在
csv.reader()中进行
但它将返回一个迭代器,该迭代器将根据请求读取文件。这意味着我们将永远不会存储每个文件超过一行(多或少)。我明白了,好吧,我也会尝试一下。
itertools.izip
内存效率不是更高吗?OP(大概是这样的)使用Python2,因此
zip
将耗尽两个迭代器,并将两个文件读入内存。为了避免这种情况,我们需要使用
itertools.izip
这里的实际读取发生在哪里。它是一次读取整个文件吗?@user3752900文件读取将在
csv.reader()中进行
但它将返回一个迭代器,该迭代器将根据请求读取文件。这意味着我们将永远不会存储每个文件超过一行(多或少)。我知道了,好的,我也将尝试此操作。这看起来像我正在寻找的,谢谢!现在将测试这看起来像我正在寻找的,谢谢!现在将测试吗