2012-06-19 600 views
4

我有两个csv文件,我需要比较,然后吐出differnces:比较两个CSV文件,并获得差异

CSV格式:

Name Produce Number 
Adam Apple  5 
Tom Orange 4 
Adam Orange 11 

我需要比较两个CSV文件,然后告诉我,在表格和表格2上是否存在亚当斯苹果之间的差异,并为所有名字和数字做这些事情。两个CSV文件都将被格式化。

任何指针将不胜感激

+0

您正在使用什么版本的Python:下面的例子使用一个粗略的对比各行进行比较? – SomeKittens

+0

你已经用'excel'标记了这个标签,但是提到了CSV文件。你需要使用xlsx或xls文件吗?您可能会发现'diff'可以满足您的需要,但您并没有真正说过这是否需要大量工作并构建到现有的Python程序中。 – ChrisP

+0

对不起,你会编辑 –

回答

0

这里不使用difflib一个开始。这只是建立起来的一点,因为也许亚当和苹果在纸上出现两次;你能确保不是这样吗?苹果应该总结还是错误​​?

import csv 
fsock = open('sheet.csv','rU') 
rdr = csv.reader(fsock) 
sheet1 = {} 
for row in rdr: 
    name, produce, amount = row 
    sheet1[(name, produce)] = int(amount) # always an integer? 
fsock.close() 
# repeat the above for the second sheet, then compare 

你明白了吗?

1
import csv 

def load_csv_to_dict(fname, get_key, get_data): 
    with open(fname, 'rb') as inf: 
     incsv = csv.reader(inf) 
     incsv.next() # skip header 
     return {get_key(row):get_data(row) for row in incsv} 

def main(): 
    key = lambda r: tuple(r[0:2]) 
    data = lambda r: int(r[2]) 
    f1 = load_csv_to_dict('file1.csv', key, data) 
    f2 = load_csv_to_dict('file2.csv', key, data) 

    f1keys = set(f1.iterkeys()) 
    f2keys = set(f2.iterkeys()) 

    print("Keys in file1 but not file2:") 
    print(", ".join(str(a)+":"+str(b) for a,b in (f1keys-f2keys))) 

    print("Keys in file2 but not file1:") 
    print(", ".join(str(a)+":"+str(b) for a,b in (f2keys-f1keys))) 

    print("Differing values:") 
    for k in (f1keys & f2keys): 
     a,b = f1[k], f2[k] 
     if a != b: 
      print("{}:{} {} <> {}".format(k[0],k[1], a, b)) 

if __name__=="__main__": 
    main() 
+0

当我在IDLE中尝试这个时,我得到这个:http://pastebin.com/6U035ERr(使用pastebin所以你可以看到格式化的整个错误信息) –

4

如果您的CSV文件没有那么大,他们会带给你的机器瘫痪,如果将其加载到内存中,那么你可以尝试这样的:

import csv 
csv1 = list(csv.DictReader(open('file1.csv'))) 
csv2 = list(csv.DictReader(open('file2.csv'))) 
set1 = set(csv1) 
set2 = set(csv2) 
print set1 - set2 # in 1, not in 2 
print set2 - set1 # in 2, not in 1 
print set1 & set2 # in both 

对于大文件,你可以将它们加载到SQLite3数据库中,并使用SQL查询来完成相同的操作,或者通过相关键进行排序,然后进行匹配合并。

+1

The csv1列表中的字符串不可散列,因此创建set1将不可能。这可以通过使用[json.dumps]将字典转换为字符串来避免(http://docs.python.org/2/library/json.html) –

+1

@HK_CK好的,我很高兴为您添加回答...只是不改变它,因为你suggedted ... –

+2

TypeError:不可能的类型:'字典'。来吧! –

1

如果您想要将Python的csv模块和函数发生器一起使用,可以使用嵌套循环并比较大的.csv文件。

import csv 

def csv_lazy_get(csvfile): 
    with open(csvfile) as f: 
     r = csv.reader(f) 
     for row in r: 
      yield row 

def csv_cmp_lazy(csvfile1, csvfile2): 
    gen_2 = csv_lazy_get(csvfile2) 

    for row_1 in csv_lazy_get(csvfile1): 
     row_2 = gen_2.next() 

     print("row_1: ", row_1) 
     print("row_2: ", row_2) 

     if row_2 == row_1: 
      print("row_1 is equal to row_2.") 
     else: 
      print("row_1 is not equal to row_2.") 

    gen_2.close() 
相关问题