маркировка дубликатов в CSV-файле - PullRequest
2 голосов
/ 14 ноября 2009

Я озадачен проблемой, показанной в примере ниже:

"ID","NAME","PHONE","REF","DISCARD"
1,"JOHN",12345,,
2,"PETER",6232,,
3,"JON",12345,,
4,"PETERSON",6232,,
5,"ALEX",7854,,
6,"JON",12345,,

Я хочу обнаружить дубликаты в столбце «ТЕЛЕФОН» и пометить последующие дубликаты с помощью столбца «REF», указав значение «ID» первого элемента и значение «Да» для «ОТКЛ.» колонка

"ID","NAME","PHONE","REF","DISCARD"
1,"JOHN",12345,1,
2,"PETER",6232,2,
3,"JON",12345,1,"Yes"
4,"PETERSON",6232,2,"Yes"
5,"ALEX",7854,,
6,"JON",12345,1,"Yes"

Итак, как мне это сделать? Я попробовал этот код, но моя логика, конечно, была неправильной.

import csv
myfile = open("C:\Users\Eduardo\Documents\TEST2.csv", "rb")
myfile1 = open("C:\Users\Eduardo\Documents\TEST2.csv", "rb")

dest = csv.writer(open("C:\Users\Eduardo\Documents\TESTFIXED.csv", "wb"), dialect="excel")

reader = csv.reader(myfile)
verum = list(reader)
verum.sort(key=lambda x: x[2])
for i, row in enumerate(verum):
    if row[2] == verum[i][2]:
        verum[i][3] = row[0]

print verum

Ваше руководство и помощь будут высоко оценены.

Ответы [ 5 ]

7 голосов
/ 14 ноября 2009

Единственное, что вы должны хранить в памяти во время работы, - это сопоставление телефонных номеров с их идентификаторами.

map = {}
with open(r'c:\temp\input.csv', 'r') as fin:
    reader = csv.reader(fin)
    with open(r'c:\temp\output.csv', 'w') as fout:
        writer = csv.writer(fout)
        # omit this if the file has no header row
        writer.writerow(next(reader))
        for row in reader:
            (id, name, phone, ref, discard) = row
            if map.has_key(phone):
                ref = map[phone]
                discard = "YES"
            else:
                map[phone] = id
            writer.writerow((id, name, phone, ref, discard))
0 голосов
/ 24 ноября 2009

Я работаю с большими 40k плюс записи CSV-файлов, самый простой способ избавиться от дубликатов его с помощью Access. 1. Создать новую базу данных, 2, вкладка Таблицы Получить внешние данные 3. Сохранить таблицу. 4. Вкладка «Запросы» Новый мастер поиска дубликатов (Совпадение по полю телефона, отображение всех полей и подсчет) 5. Сохранить запрос (экспорт имеет .txt, но имя dupes.txt) 6. Импортируйте результат запроса как новую таблицу, не импортируйте поле с числом дубликатов. 7. Запрос Найти несоответствие (сопоставить по полю телефона, показать все поля в результате. Сохранить запрос, затем экспорт имеет .txt, но имя unique.txt) 8. Импорт уникального файла в существующую таблицу (дубликаты) 9.Вы теперь можете сохранять и экспортировать снова в любой тип файла, который вам нужен, и без каких-либо дубликатов

0 голосов
/ 14 ноября 2009
from operator import itemgetter
from itertools import groupby

import csv
verum = csv.reader(open('data.csv','rb'))

verum.sort(key=itemgetter(2,0))
def grouper( verum ):
    for key, grp in groupby(verum,itemgetter(2)):
        # key = phone number, grp = records with that number
        first = grp.next()
        # first item gets its id written into the 4th column
        yield [first[0],first[1],first[2],first[0],''] #or list(itemgetter(0,1,2,0,4)(first)) 
        for x in grp:
            # all others get the first items id as ref
            yield [x[0],x[1],x[2], first[0], "Yes"]

for line in sorted(grouper(verum), key=itemgetter(0)):
    print line

Выходы:

['1', 'JOHN', '12345', '1', '']
['2', 'PETER', '6232', '2', '']
['3', 'JON', '12345', '1', 'Yes']
['4', 'PETERSON', '6232', '2', 'Yes']
['5', 'ALEX', '7854', '5', '']
['6', 'JON', '12345', '1', 'Yes']

Запись данных оставлена ​​читателю; -)

0 голосов
/ 14 ноября 2009

Я знаю одну вещь. Я знаю, что для этого не нужно читать весь файл в память.

import csv
myfile = "C:\Users\Eduardo\Documents\TEST2.csv"

dest = csv.writer(open("C:\Users\Eduardo\Documents\TESTFIXED.csv", "wb"), dialect="excel")

phonedict = {}

for row in cvs.reader(open(myfile, "r")):
    # setdefault sets the value to the second argument if it hasn't been set, and then
    # returns what the value in the dictionary is.
    firstid = phonedict.setdefault(row[2], row[0])
    row[3] = firstid
    if firstid is not row[0]:
       row[4] = "Yes"
    dest.writerow(row)
0 голосов
/ 14 ноября 2009

Звучит как домашнее задание. Поскольку это CSV-файл (и, следовательно, изменить размер записи практически невозможно), лучше всего загрузить весь файл в память и манипулировать им, прежде чем записать его в новый файл. Создайте список строк, который является исходными строками файла. Затем создайте карту, вставьте в номер телефона (ключ) и значение (идентификатор). Перед вставкой вы ищете номер, если он уже существует, вы обновляете строку, содержащую повторяющийся номер телефона. Если его нет на карте, вставьте пару (телефон, идентификатор).

...