Поиск дубликатов записей в поле с помощью ArcGIS for Desktop?


9

Я ищу дубликаты записей в файлах DBF на основе атрибута с именем «ID». У меня есть различные файлы DBF от 500 000 записей до 1,5 миллиона, и я знаю, что есть множество дубликатов.

Я хотел бы добавить поле «Дублировать», которое говорит «Да» или «Нет» (или 1 или 0 в порядке), когда атрибут идентификатора присутствует в другом месте. При использовании следующего скрипта Python в Field Calculator возвращается 1 для дублированной записи и 0 для уникальной записи;

uniqueList = []
def isDuplicate(inValue):
  if inValue in uniqueList:
    return 1
  else:
    uniqueList.append(inValue)
    return 0
isDuplicate(!FIELD_NAME!)

Однако 1-я запись, например, 5 дубликатов идентификаторов также будет возвращена как 0 (последующие 4 считаются дубликатами). Мне нужно, чтобы все 5 были отмечены как дубликаты, поскольку идентификатор существует в другом месте.

Использование следующего кода даст вам дополнительный подсчет того, сколько раз этот идентификатор встречается, причем 1 означает 1-й случай и т. Д .;

UniqueDict = {}
def isDuplicateIndex(inValue):
    UniqueDict.setdefault(inValue,0)
    UniqueDict[inValue] += 1
    return UniqueDict[inValue]

isDuplicateIndex( !YOUR_FIELD! )

Я просто хочу 1 (или Да), если идентификатор этой записи существует в другом месте! (ArcGIS версия 10.1)

Я видел другие ответы, такие как сценарий Python для определения дубликатов записей (продолжение), но это не совсем работает.

Ответы:


11

Альтернативное решение состоит в том, чтобы использовать существующий инструмент « сводной статистики » в ArcGIS, а затем вы присоединяете итоговую таблицу на основе вашего поля ID. Дубликаты будут иметь «COUNT» больше 1, поэтому его легко вычислить с помощью полевого калькулятора.


Как ваш метод достигает назначения первой дублирующейся записи, найденной как '0'?
artwork21

@ radouxju Спасибо за ваш ответ, я могу видеть, сколько полигонов являются дубликатами, просто выбрав по атрибуту сейчас. Удивил, что это не пришло мне в голову, когда все вещи Python сделали!
Сэм

@ artwork21 я не хотел, чтобы 1-й дубликат был равен 0, я хотел, чтобы все, у кого был дубликат, было «ДА», или сейчас - как есть - число больше 1
Сэм

@ Сэм, о чем ты говоришь в этом утверждении, «однако первая запись, например, 5 дубликатов идентификаторов также будет возвращена как 0;»?
artwork21

@ artwork21. Извините, я думаю, что моя оригинальная формулировка была не очень ясной, я исправлю. Я пытался сказать, что если все 5 записей имеют одинаковый идентификатор, то этот фрагмент кода Python идентифицирует 1-й экземпляр как уникальный идентификатор, а последующие 4 - как дубликаты. Я хотел, чтобы все 5 были помечены как дубликаты (то есть этот идентификатор существовал в другом месте)
Сэм,

1

Другое альтернативное решение ( работает только со средами SDE ) заключается в использовании существующих функций SQL в ArcGIS для отображения дубликатов записей.

Получить повторяющиеся записи в таблице (выбор по атрибуту)

[FIELD_NAME] In (SELECT [FIELD_NAME] FROM [TABLE_NAME] GROUP BY [FIELD_NAME] HAVING Count(*)>1 )

Пример:

ID In (SELECT ID FROM GISDATA.MY_TABLE GROUP BY ID HAVING Count(*)>1 )

Можете ли вы заставить это работать в файловой базе геоданных? Запрос успешно работает в личной базе геоданных, но когда я пытаюсь запустить его в файловой базе геоданных, он завершается с сообщением «Использован недопустимый оператор SQL». Редактировать: по ссылке на документацию в файловых базах геоданных поддерживаются только ограниченные подзапросы.
isburns

Запрос копируется прямо из вашего поста и ссылается на правильные имена таблиц и полей. Запрос действителен, когда я удаляю HAVING COUNT(*) > 1. Я действительно не вижу способа заставить его работать в файловых базах геоданных. Я знаю, что эта техническая статья несколько устарела, но, похоже, она является источником вашего оператора SQL и указывает на то, что он не работает в файловых базах геоданных. Я готов объявить ваш ответ, если смогу заставить его работать в файле gdbs, или добавлено пояснение, указывающее, что они являются исключением.
isburns

@isburns Я ошибся, работает в среде SDE, а не в файловой базе геоданных. Единственное, что вы можете сделать в качестве обходного пути, - это перенести данные таблиц в Excel, найти дубликаты и затем присоединиться к списку дубликатов обратно в ArcGIS, который затем будет показывать только эти записи, не идеальные, но работающие.
Тристан Форвард

1
Спасибо за обновления. Я проголосовал за ваш ответ, потому что он работает и довольно прост и быстр в поддерживаемых базах геоданных. Я знаю, что это сейчас в комментариях, но вы можете также отредактировать сам пост, чтобы указать, что он работает в персональных базах и базах геоданных SDE, но не в файловых базах геоданных или шейп-файлах.
isburns

0

Следующий скрипт создает новое поле с количеством вхождений каждого значения из указанного поля. Так, например, если у вас есть «Париж» 6 раз в этом поле, каждый ряд с «Парижем» получит 6.

import arcpy

arcpy.env.workspace=r"D:\test.gdb"
infeature="sample_feature"
field_in="sample_field"
field_out="COUNT_"+field_in

#create the field for the count values
arcpy.AddField_management(infeature,field_out,"SHORT")

#creating the list with all the values in the field, including duplicates
lista=[]
cursor1=arcpy.SearchCursor(infeature)
for row in cursor1:
    i=row.getValue(field_in)    
    lista.append(i)
del cursor1, row

#updating the count field with the number on occurrences of field_in values
#in the previously created list
cursor2=arcpy.UpdateCursor(infeature)
for row in cursor2:
    i=row.getValue(field_in)
    occ=lista.count(i)   
    row.setValue(field_out,occ)
    cursor2.updateRow(row)
del cursor2, row
print ("Done.")

Его можно легко изменить, чтобы иметь значение «Да» или « 1», если число> 1, но я полагаю, что полезнее иметь фактическое число.

Позже Редактировать: Или вы можете использовать это в полевом калькуляторе. Код пре-логического кода:

infeature="sample_feature" #change with the name of your feature
lista=[]
field="sample_field" #change with your field with duplicates
cursor1=arcpy.SearchCursor(infeature)
for row in cursor1:
    i=row.getValue(field)    
    lista.append(i)
del cursor1, row

def duplicates(field_in):        
    occ=lista.count(field_in)
    return occ

дубликат поля =

duplicates(!sample_field!)
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.