基于两列删除csv文件中的重复项?

时间:2015-09-30 16:35:39

标签: csv python-3.x conditional duplicate-removal

我有一个必须读取的CSV,并且在写入之前删除了重复值。

重复值将基于两列(日期,价格)(AND条件语句)。因此,在下面的示例中,第1行,第2行和第4行将写入CSV。第3行符合重复条件(因为相同的日期和价格匹配第1行)并且将被排除(不写入CSV)。

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 个答案:

答案 0 :(得分: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 :(得分: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)

这种方法的缺点是您的所有数据都会立即读入内存。但是,如果您的数据集非常适合记忆,那么可能值得增加清晰度和表现力 - 特别是如果您要对这样的表格数据进行额外的操作。

答案 2 :(得分: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)