I have an ID number field and some of the numbers are missing. I know I can identify duplicate numbers in a number field, but can I identify missing numbers. There are almost 5000 numbers and to search for them manually is painful. Thanks.
In terms of performance, the following will be better since it recycles the same cursor instead of recreating cursors:
fc <SPAN class="operator token">=</SPAN> <SPAN class="comment token"># path to feature class</SPAN> <SPAN class="keyword token">with</SPAN> arcpy<SPAN class="punctuation token">.</SPAN>da<SPAN class="punctuation token">.</SPAN>SearchCursor<SPAN class="punctuation token">(</SPAN>fc<SPAN class="punctuation token">,</SPAN> <SPAN class="string token">"OID@"</SPAN><SPAN class="punctuation token">)</SPAN> <SPAN class="keyword token">as</SPAN> cur<SPAN class="punctuation token">:</SPAN> min_oid<SPAN class="punctuation token">,</SPAN> <SPAN class="operator token">=</SPAN> min<SPAN class="punctuation token">(</SPAN>cur<SPAN class="punctuation token">)</SPAN> cur<SPAN class="punctuation token">.</SPAN>reset<SPAN class="punctuation token">(</SPAN><SPAN class="punctuation token">)</SPAN> max_oid<SPAN class="punctuation token">,</SPAN> <SPAN class="operator token">=</SPAN> max<SPAN class="punctuation token">(</SPAN>cur<SPAN class="punctuation token">)</SPAN> cur<SPAN class="punctuation token">.</SPAN>reset<SPAN class="punctuation token">(</SPAN><SPAN class="punctuation token">)</SPAN> missing_oids <SPAN class="operator token">=</SPAN> set<SPAN class="punctuation token">(</SPAN>range<SPAN class="punctuation token">(</SPAN>min_oid<SPAN class="punctuation token">,</SPAN> max_oid <SPAN class="operator token">+</SPAN> <SPAN class="number token">1</SPAN><SPAN class="punctuation token">)</SPAN><SPAN class="punctuation token">)</SPAN> <SPAN class="operator token">-</SPAN> set<SPAN class="punctuation token">(</SPAN>oid <SPAN class="keyword token">for</SPAN> oid<SPAN class="punctuation token">,</SPAN> <SPAN class="keyword token">in</SPAN> cur<SPAN class="punctuation token">)</SPAN><SPAN class="line-numbers-rows"><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN></SPAN>
Try using Python sets to your advantage:
fc <SPAN class="operator token">=</SPAN> <SPAN class="comment token"># path to feature class</SPAN> min_oid<SPAN class="punctuation token">,</SPAN> <SPAN class="operator token">=</SPAN> min<SPAN class="punctuation token">(</SPAN>arcpy<SPAN class="punctuation token">.</SPAN>da<SPAN class="punctuation token">.</SPAN>SearchCursor<SPAN class="punctuation token">(</SPAN>fc<SPAN class="punctuation token">,</SPAN> <SPAN class="string token">"OID@"</SPAN><SPAN class="punctuation token">)</SPAN><SPAN class="punctuation token">)</SPAN> max_oid<SPAN class="punctuation token">,</SPAN> <SPAN class="operator token">=</SPAN> max<SPAN class="punctuation token">(</SPAN>arcpy<SPAN class="punctuation token">.</SPAN>da<SPAN class="punctuation token">.</SPAN>SearchCursor<SPAN class="punctuation token">(</SPAN>fc <SPAN class="punctuation token">,</SPAN><SPAN class="string token">"OID@"</SPAN><SPAN class="punctuation token">)</SPAN><SPAN class="punctuation token">)</SPAN> missing_oids <SPAN class="operator token">=</SPAN> set<SPAN class="punctuation token">(</SPAN>range<SPAN class="punctuation token">(</SPAN>min_oid<SPAN class="punctuation token">,</SPAN> max_oid <SPAN class="operator token">+</SPAN> <SPAN class="number token">1</SPAN><SPAN class="punctuation token">)</SPAN><SPAN class="punctuation token">)</SPAN> <SPAN class="operator token">-</SPAN> set<SPAN class="punctuation token">(</SPAN>oid <SPAN class="keyword token">for</SPAN> oid<SPAN class="punctuation token">,</SPAN> <SPAN class="keyword token">in</SPAN> arcpy<SPAN class="punctuation token">.</SPAN>da<SPAN class="punctuation token">.</SPAN>SearchCursor<SPAN class="punctuation token">(</SPAN>fc<SPAN class="punctuation token">,</SPAN><SPAN class="string token">"OID@"</SPAN><SPAN class="punctuation token">)</SPAN><SPAN class="punctuation token">)</SPAN><SPAN class="line-numbers-rows"><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN></SPAN>
You can calculate your own sequential id field, then compare... the expression is seq_count( first_id_in_field)
Do note that geodatabases use 1 as first OBJECTID
cnt <SPAN class="operator token">=</SPAN> <SPAN class="number token">0</SPAN> <SPAN class="comment token"># ---- change to 1 if using a geodatabase, 0 for shapefile</SPAN> <SPAN class="keyword token">def</SPAN> <SPAN class="token function">seq_count</SPAN><SPAN class="punctuation token">(</SPAN>val<SPAN class="punctuation token">)</SPAN><SPAN class="punctuation token">:</SPAN> <SPAN class="keyword token">global</SPAN> cnt <SPAN class="keyword token">if</SPAN> cnt <SPAN class="operator token">>=</SPAN> val <SPAN class="punctuation token">:</SPAN> cnt <SPAN class="operator token">+=</SPAN> <SPAN class="number token">1</SPAN> <SPAN class="keyword token">return</SPAN> cnt <SPAN class="comment token"># __esri_field_calculator_splitter__</SPAN> seq_count<SPAN class="punctuation token">(</SPAN><SPAN class="number token">0</SPAN><SPAN class="punctuation token">)</SPAN> <SPAN class="comment token"># ----- change to 1 if using a geodatabase</SPAN><SPAN class="line-numbers-rows"><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN></SPAN>
You can then query where the OBJECTID or FID isn't equal to the result you calculate. The big problem is that as soon as it hits a difference then you have to edit it and restart the process.
Another method is to calculate the difference between the previous and current. The following isn't tested so no guarantees... but I am sure someone will test and fix it
diff <SPAN class="operator token">=</SPAN> <SPAN class="number token">0</SPAN> <SPAN class="keyword token">def</SPAN> <SPAN class="token function">seq_diff</SPAN><SPAN class="punctuation token">(</SPAN>val<SPAN class="punctuation token">)</SPAN><SPAN class="punctuation token">:</SPAN> <SPAN class="keyword token">global</SPAN> diff <SPAN class="keyword token">if</SPAN> val <SPAN class="operator token">-</SPAN> diff <SPAN class="operator token">!=</SPAN> <SPAN class="number token">1</SPAN> <SPAN class="punctuation token">:</SPAN> diff <SPAN class="operator token">=</SPAN> val <SPAN class="keyword token">return</SPAN> <SPAN class="operator token">-</SPAN><SPAN class="number token">999</SPAN> <SPAN class="keyword token">else</SPAN><SPAN class="punctuation token">:</SPAN> diff <SPAN class="operator token">+=</SPAN> <SPAN class="number token">1</SPAN> <SPAN class="keyword token">return</SPAN> diff seq_diff<SPAN class="punctuation token">(</SPAN>!OBJECTID!<SPAN class="punctuation token">)</SPAN> <SPAN class="comment token"># ---- or !FID! for shapefiles</SPAN><SPAN class="line-numbers-rows"><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN></SPAN>
Aangemelde leden kunnen berichten plaatsen, updates volgen en meer. Nieuw hier? Registreer een gratis account.
Find useful guides, FAQs, and documents to help you navigate and make the most of Esri Community.