Python 读取CSV并根据两列(很多列中的两列)中的值删除重复值

Python 读取CSV并根据两列(很多列中的两列)中的值删除重复值,python,csv,python-3.x,duplicates,Python,Csv,Python 3.x,Duplicates,[使用Python3]我有一个csv文件,我想读取并删除一个“特殊”的重复文件。脚本应将删除重复数据的csv输出到csv,同时尊重标题 最好是举例说明。csv文件如下所示: ID Name HeaderX HeaderY HeaderZ ... 1 A string float string ... 1 A string float string ... 1 A string float string ... 2

[使用Python3]我有一个csv文件,我想读取并删除一个“特殊”的重复文件。脚本应将删除重复数据的csv输出到csv,同时尊重标题

最好是举例说明。csv文件如下所示:

ID  Name    HeaderX HeaderY HeaderZ ...
1   A       string  float   string  ...
1   A       string  float   string  ...
1   A       string  float   string  ...
2   A       string  float   string  ...
2   B       string  float   string  ...
3   A       string  float   string  ...
4   B       string  float   string  ...
5   C       string  float   string  ...
6   D       string  float   string  ...
... ...     ...     ...     ...     ...
这里有ID=1和ID=2的重复行,但是我想保留名称相同的所有重复行。所以在这个例子中,我想保留ID=1的所有实例,但删除ID=2的所有实例。换句话说,删除名称包含1个以上变体的所有重复行。(这有道理吗?!)

目前我有以下基于线程的代码(如下)。但是,它的作用正好相反,基于这两列删除重复项,保留ID=2的所有实例,并删除ID=1的行

另外,理想情况下,我希望脚本打印它删除的重复数

import csv

filename = 'testing.csv'
outfile = 'outfile.csv'

with open(outfile, 'w') as fout:
    writer = None
    entries = set()
    with open(filename, 'r') as fin:
        reader = csv.DictReader(fin)

        if not writer:
            writer = csv.DictWriter(fout, lineterminator='\n', fieldnames=reader.fieldnames)
            writer.writeheader()

        for row in reader:
            key = (row['ID'], row['Name'])

            if key not in entries:
                writer.writerow(row)
                entries.add(key)

如果行是按ID排序的,则可以使用以下代码

import csv
import itertools
import operator

filename = 'testing.csv'
outfile = 'outfile.csv'
ndups = 0

with open(filename, 'r') as fin, open(outfile, 'w') as fout:
    reader = csv.DictReader(fin)
    writer = csv.DictWriter(fout, lineterminator='\n', fieldnames=reader.fieldnames)
    for id_, grp in itertools.groupby(reader, key=operator.itemgetter('ID')):
        rows = list(grp)
        if len({row['Name'] for row in rows}) > 1:
            ndups += len(rows)
            continue
        writer.writerows(rows)

print('{} duplicates.'.format(ndups))

嗨,falsetru,看起来这确实有效!关于打印副本的数量,我有其他想法(只返回副本的总数),但我会尝试将其考虑在内。实际上,我不完全确定行是否总是按ID排序。您是否也有解决方案?@Matthijs,csv文件有多大?在itertools.groupby(排序(reader,key=operator.itemgetter('id')),key=operator.itemgetter('id')):中,将…的
行替换为id\ugrp的
,然后它将用于未排序的数据。太棒了!谢谢你。CSV文件实际上可能有数百万行。