比较两个CSV文件并使用Python导出非匹配

2024-09-30 18:26:58 发布

您现在位置:Python中文网/ 问答频道 /正文

作为一个使用Python的初学者,我又被卡住了!我有两个CSV文件,如下所示:

CSV1(主列表)

ID    Name    Code.    Prop
12    SAB     1234     ZXC
12    SAB     1236     ZXC
12    SAB     1233     ZXC
12    SAB     1234     ZXC
11    ASN     1234     ABV
16    HGF     1233     AAA
19    MAB     8765     BCT
19    MAB     8754     BCT

CSV2(子集)

^{pr2}$

我的目标是尝试使用csv第一列中的值来比较和识别CSV2中没有出现的值。在

编辑 所以在上面的示例中,CSV1(主列表)中ID为11和16的行应该被导出。在

有些事情要考虑。ID虽然唯一,但在两个CSV文件中都有多个实例(如上面CSV文件中的示例数据所示)。在

我在这个网站上浏览了一些帖子,比如this one。我试图达到的目标与这里所要求的完全相反,但我无法理解这条线索的解决方案。在

我试图得到一些结果,但没有成功。我在下面附上了我正在使用的代码:

import csv

fOpen1=open('C:\Master.csv')
fOpen2=open('C:\Subset.csv')
fOutput1=open('C:\Untagged.csv', 'wb')


master=csv.reader(fOpen1)
subset=csv.reader(fOpen2)
untagged=csv.writer(fOutput1)


count=0

subsetCopy=list()

header1=master.next()
header2=subset.next()

untagged.writerow(header1)


for row2 in subset:
    subsetCopy.append(row2)


for row1 in master:
    for row2 in subsetCopy:
        if row1[0] != row2[0]:
            count=count+1
            untagged.writerow(row1)

print count

当我运行这个程序时,我得到的结果非常荒谬,以百万计。奇怪的是我使用了完全相同的代码而没有!=(改为使用==来实现另一个目标,而且效果很好。我认为改变等式条件会得到相反的结果。相反,它最终生成了一个巨大的csv文件,没有任何有用的东西。 我也试着用一本字典,但后来意识到它可能行不通,因为两个文件中都有重复的记录。对于我来说,在两个文件中获取特定行的所有实例是很重要的。在

我哪里出错了?欢迎提出任何建议。在


Tags: 文件csvmasterid目标forcountopen
3条回答

对于第一部分,即使您在子集中找到了master中的一行,您也可以继续将其与其他行进行比较,并将其添加到untaged中。在

你的for循环应该是:

for row1 in master:
    for row2 in subsetCopy:
        if row1[0] == row2[0]: 
            break
    else:
        count=count+1
        untagged.writerow(row1)

也就是说:如果该行在子集中的任何位置,则忽略它,并且只在遍历subset2而没有找到它的情况下计算它。在

首先,您需要使用一个^{},这将使这个快很多。在

也就是说,你要比较文件1的每一行和文件2的每一行。如果它们不匹配(常见情况下),则将它们添加到untagged列表中。在

需要注意的是,对于包含多行的任何文件,所有行都有不匹配的行,这会导致它们多次写入结果。在

设置操作包含在set中,您可以将它们用于您自己的目的,具体地说,区别如下:

new set with elements in s but not in t

set operations table

以下是需要进行的更改:

使用generator expressionssubsetmaster中的所有关键元素创建一个集合:

subsetSet = set(s[0] for s in subset)
masterSet = set(m[0] for m in master)

找出关键要素的区别:

^{pr2}$

现在,当您从主机读取时,请使用这些键,以便只读取未标记的行:

with open('C:\Master.csv') as f:
    master = csv.reader(f)
    untagged = [m for m in master if m and m[0] in untagged_keys]

print untagged

你做错的是这个循环-

for row1 in master:
    for row2 in subsetCopy:
        if row1[0] != row2[0]:
            count=count+1
            untagged.writerow(row1)

对于master中的每一行1,它会将id与row2(使用id)进行比较,然后如果它们不相等,则将该行1写入未标记。这将导致row1被写入untagged很多次,就像subsetCopy中有不相关的行一样,这不是检查{}的id是否存在于子集中的方法。在

您需要首先遍历subsetCopy中的每一行,然后将其保存在一个集合中,然后将要检查的内容与该集合进行比较。示例-

^{pr2}$

相关问题 更多 >