Sort feature class field permanently

819
14
05-16-2023 03:13 PM
2Quiker
Occasional Contributor II

I need to permanently sort a feature class field so I can add a sequential number based on the sort. I know I can use the sort tool, but I want to sort the existing feature without having to create another feature class. I am able to do the sequential number with the following but I need the feature class "Sub_Name" sorted. anyone have an example of how to accomplish this?

 

import arcpy
from itertools import count
cntr = count()

fc = 'C:\Temp\SUBS.shp'
with arcpy.da.UpdateCursor(fc,["ID","SUB_NAME"],sql_clause=(None,"ORDER BY SUB_NAME")) as cur:
    for i, j in cur:
        cur.updateRow([next(cntr), j])

 

0 Kudos
14 Replies
DavidPike
MVP Frequent Contributor

Sort tool then truncate and append the data back into the original.  No easy way to do in-place as far as I know.  Maybe an update cursor but it's the same principle but more convoluted.

0 Kudos
BlakeTerhune
MVP Regular Contributor

You should read the documentation.

DISTINCTORDER BY, and ALL are only supported when working with databases. They are not supported by other data sources (such as dBASE or INFO tables).

TOP is only supported bySQL Serverdatabases.

For a shapefile, you will need to read all the data into a list, and then enumerate the sorted list. Here's an untested code sample.

 

import arcpy

subs_shp = 'C:\Temp\SUBS.shp'

sub_name_values = [row[0] for row in arcpy.da.SearchCursor(subs_shp,["SUB_NAME"])]

sub_name_id = {}
for enum, sub_name in enumerate(sorted(sub_name_values)):
    sub_name_id[sub_name] = enum

with arcpy.da.UpdateCursor(subs_shp,["ID","SUB_NAME"]) as u_cursor:
    for id, sub_name in u_cursor:
        id = sub_name_id[sub_name]
        u_cursor.updateRow([id, sub_name])

 

 

 

0 Kudos
2Quiker
Occasional Contributor II

Blake, this is helpful but it doesn't physically change the order of the SUB_NAME field.

I have the following and it does sort the SUB_NAME field of the  shapefile but somehow it spatially moves the features, not sure why.

Would it best to place this shapefile in to a file geodatabase?

fc = 'C:\Temp\SUBS.shp'

datatosort = [] 
with arcpy.da.SearchCursor(fc,"*") as cursor: 
    for row in cursor: 
       datatosort.append(row) 

subindex = 2
rowindex = 0 
datatosort.sort(key=lambda tup: tup[subindex]) 

with arcpy.da.UpdateCursor(fc,"*") as cursor: 
    for row in cursor: 
       row = datatosort[rowindex] 
       rowindex += 1 
       cursor.updateRow(row)

 

0 Kudos
BlakeTerhune
MVP Regular Contributor

@2Quiker wrote:

Blake, this is helpful but it doesn't physically change the order of the SUB_NAME field.


I can't think of a practical reason why you would need to reorder the records in the table. Every method for viewing the data allows for sorting it as needed. If you wanted to change the order of the records in the table (beyond an ad hoc sort), you need to recreate the table. May I ask what your requirement is that you need to reorder the rows in the table?


@2Quiker wrote:

Would it best to place this shapefile in to a file geodatabase?


Yes. When working with Esri products, I highly recommend using a file geodatabase over a shapefile. You can always export it back to a shapefile later if you need to share it that way.

0 Kudos
2Quiker
Occasional Contributor II

That .dbf of that shapefile is using in a different reporting system. I was trying to save having to manually sort every time the .dbf is used. I run this reporting once a day or sometimes more often.

0 Kudos
BlakeTerhune
MVP Regular Contributor

When you create the shapefile, you'll have to do it row by row, no export or update. Do you need a shapefile (with geometry) or can it be just a table of values (CSV)?

 

0 Kudos
2Quiker
Occasional Contributor II

I need a shapfile with geometry.

0 Kudos
BlakeTerhune
MVP Regular Contributor

Are you creating it from a shapefile or a geodatabase feature class?

0 Kudos
2Quiker
Occasional Contributor II

I will take your advice and create it in a geodatabase.

0 Kudos