基于两列,如何在CSV文件中去除重复数据?

4
我有一个CSV文件,必须在写入之前读取并删除重复的值。
根据两列(日期、价格)进行去重(AND条件语句)。因此,在下面的示例中,行1、行2和行4将被写入CSV。行3将被排除(不写入CSV),因为与行1相同的日期和价格匹配。
address      floor       date         price
40 B STREET    18        3/29/2015    2200000
40 B STREET    23        1/7/2015     999000
40 B STREET    18        3/29/2015    2200000
40 B STREET    18        4/29/2015    2200000
3个回答

1
你可以使用DictReaderDictWriter来完成你的任务。
import csv

def main():
"""Read csv file, delete duplicates and write it."""
    with open('test.csv', 'r',newline='') as inputfile:
        with open('testout.csv', 'w', newline='') as outputfile:
            duplicatereader = csv.DictReader(inputfile, delimiter=',')
            uniquewrite = csv.DictWriter(outputfile, fieldnames=['address', 'floor', 'date', 'price'], delimiter=',')
            uniquewrite.writeheader()
            keysread = []
            for row in duplicatereader:
               key = (row['date'], row['price'])
               if key not in keysread:
                   print(row)
                   keysread.append(key)
                   uniquewrite.writerow(row)

if __name__ == '__main__':
    main()

1

虽然不在标准库中,但pandas非常适合这种情况:

import pandas as pd
records = pd.read_csv('test.csv')
deduped = records.drop_duplicates(['date', 'price'])
deduped.to_csv('deduped.csv', index=False)

这种方法的缺点是一次性将所有数据读入内存中。但是,如果你的数据集适合内存,采用这种方法可能会增加清晰度和表达能力-特别是如果你将要对这样的表格数据进行其他操作。

0
你可以使用 set 来保存已写入的行,在每次迭代中检查是否已经写入该行,如果已经写入,则不再写入,并使用 tempfile.NamedTemporaryFile 重写你的文件:
import csv
from tempfile import NamedTemporaryFile
import shutil

seen=set()
tempfile = NamedTemporaryFile(delete=False)

with open('file_name.csv', newline='') as csvfile:
     spamreader = csv.reader(csvfile, delimiter='\t')
     spamwriter = csv.writer(csvfile, delimiter='\t')
     for row in spamreader:
         date=row[2]
         if date not in seen:
            spamwriter.writerow(row)
         seen.add(date)
shutil.move(tempfile.name, file_name)

价格怎么样?我只想排除同时在之前记录中出现了“日期”和“价格”值的情况。如果只有一个先前记录中出现了日期值或价格值,则应将其包含在内。因此,这必须是一个条件语句。 - user3062459
@user3062459 所以只需将 tuple(row[2:]) 放在 seen 上并进行检查即可。 - Mazdak

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接