2013-06-21 69 views
2

[使用Python3]我有一個csv文件,我想讀取它並刪除'特殊'大小寫的重複項。該腳本應將重複的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的所有實例。換句話說,刪除名稱包含多個變體的所有重複行。 (這是否使敏感?!)

目前我有以下代碼(以下),根據this線程。然而,它完全相反,刪除基於兩列的重複項,並保留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) 

回答

2

如果行按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)) 
+0

你好,你看起來像這個實際工作!在打印重複數量方面,我有其他想法(僅僅是返回重複的總數),但我會盡力將其歸因於我自己。 – Matthijs

+0

@Matthijs,我更新了代碼。 – falsetru

+0

實際上,我並不完全確定行總是按ID排序的。你是否也有解決方案? – Matthijs