我试图比较两个csv文件,并使用python 2.7查找不同的行。当所有列不相同时,行被认为是不同的。这些文件的格式与所有相同的列相同,并且采用此格式。
oldfile.csv
ID name Date Amount
1 John 6/16/2015 $3000
2 Adam 6/16/2015 $4000
newfile.csv
ID name Date Amount
1 John 6/16/2015 $3000
2 Adam 6/16/2015 $4000
3 Sam 6/17/2015 $5000
4 Dan 6/17/2015 $6000
当我运行我的脚本时,我希望输出只是底部两行并写在csv文件中,遗憾的是我无法让我的代码正常工作。我在下面写的内容打印出oldfile.csv的内容,它不会打印不同的行。我想要的代码是打印输出到output.csv文件中的行。即
output.csv
3 Sam 6/17/2015 $5000
4 Dan 6/17/2015 $6000
这是我使用csv模块的代码python 2.7代码。
import csv
f1 = open ("olddata/olddata.csv")
oldFile1 = csv.reader(f1)
oldList1 = []
for row in oldFile1:
oldList1.append(row)
f2 = open ("newdata/newdata.csv")
newFile2 = csv.reader(f2)
newList2 = []
for row in newFile2:
newList2.append(row)
f1.close()
f2.close()
output = [row for row in oldList1 if row not in newList2]
print output
遗憾的是,代码只打印出oldfile.csv的内容。我一整天都在努力尝试不同的变化,但我根本无法让它正常工作。再次,非常感谢您的帮助。
答案 0 :(得分:5)
您目前正在检查旧文件中存在但
相反,您应检查新文件中存在的行,但不在新文件中:
output = [row for row in newList2 if row not in oldList1]
此外,您的CSV文件是TSV,因此无法正确加载。您应该指示csv
模块使用TSV打开您的文件。您的代码也可以简化。
以下是您可以使用的内容:
import csv
f1 = open ("olddata/olddata.csv")
oldFile1 = csv.reader(f1, delimiter='\t')
oldList1 = list(oldFile1)
f2 = open ("newdata/newdata.csv")
newFile2 = csv.reader(f2, delimiter='\t')
newList2 = list(newFile2)
f1.close()
f2.close()
output1 = [row for row in newList2 if row not in oldList1]
output2 = [row for row in oldList1 if row not in newList2]
print output1 + output2
答案 1 :(得分:2)
如果您的文件看起来像提供的输入,则可以使用集合:
with open("olddata/olddata.csv") as f1, open("newdata/newdata.csv") as f2:
header = next(f1).split()
st = set(f1)
with open("out.csv","w") as out:
wr = csv.writer(out,delimter="\t")
# write lines only if they are not in the set of lines from olddata/olddata.csv
wr.writerows((row.split() for row in f2 if row not in st))
您无需在newdata.csv
中创建行列表,您可以遍历文件对象并随时编写或执行任何操作。此外,with
会自动关闭您的文件。
或者没有csv模块只存储行:
with open("olddata/olddata.csv") as f1, open("newdata/newdata.csv") as f2:
header = next(f1)
st = set(f1)
with open("out.csv", "w") as out:
out.writelines((line for line in f2 if line not in st))
输出:
ID name Date Amount
3 Sam 6/17/2015 $5000
4 Dan 6/17/2015 $6000
或者使用csv模块完成所有操作:
import csv
from itertools import imap
with open("olddata/olddata.csv") as f1, open("newdata/newdata.csv") f2:
r1 = csv.reader(f1, delimiter="\t")
header = next(r1)
st = set(imap(tuple, r1))
with open("out.csv", "w") as out:
wr = csv.writer(out, delimiter="\t")
r2 = csv.reader(f2, delimiter="\t")
wr.writerows((row for row in imap(tuple, f2) if row not in st))
如果您不关心订单,并且想要显示在两者中但不在两者中的行,则可以使用set.symmetric_difference。
import csv
from itertools import imap
with open("olddata/olddata.csv") as f1, open("newdata/newdata.csv") f2:
r1 = csv.reader(f1, delimiter="\t")
header = next(r1)
st = set(imap(tuple, r1))
r2 = csv.reader(f2, delimiter="\t")
print(st.symmetric_difference(imap(tuple, r2)))
输出:
set([('ID', '', 'name', 'Date', 'Amount'), ('3', 'Sam', '6/17/2015', '$5000'), ('4', 'Dan', '6/17/2015', '$6000')])
对数据进行排序和写入仍然比使用列表更有效。