Copy and Paste specific row in the same point fc for several fclasses

4775
6
Jump to solution
03-30-2015 01:42 PM
KONPETROV
Occasional Contributor III

I have 10 point feature classes to process each of them having different name, in which i must copy and paste a specific row, updating also a specific column with new values, doing that with a loop for 10 pnts . Maybe it's easy to many of you, but as new to programming i can't understand very well how to use ArcPy for my procedure. I have written this script for the things i want to do with my point fc.

1. copy the last row which is different for each fc

2. paste it in the first row without overwritting the existing feature there

3. delete the last row i used for copy

4. update the FID column starting from 0

my tables are in the form of:

FID    SHAPE   LINEOID    VALIE

0         POINT       0            10

1         POINT       0            20

2         POINT       0            30

3         POINT       0            40

4         POINT       0            50

5         POINT       0            60

6         POINT       0            70

7..

8..

500     POINT       0             0   

If someone can answer, PLEASE it will help if responding a bit analytically about the mistakes in my script

# PURPOSE:CALCULATE THE NUMBER OF FEATURES IN A FEATURE CLASS,  Name: fcCount.py

# Import system modules

import arcpy

from arcpy import env

lyrfile = "c:/W/S/pntp.lyr"

result = arcpy.GetCount_management(lyrfile)

count = int(result.getOutput(0))

print count

       

#SELECT ANALYSIS-EXPORT SELECTED ROW/FEATURE AS PNTP2

from arcpy import env

arcpy.Select_analysis("pntp.shp", "C:/W/S/pntp2.shp", 'FID = count')

#DELETE ROW WITH UPDATE CURSOR

with arcpy.da.UpdateCursor("c:/W/S/pntp.shp",["FID"]) as cursor:

    c = max([FID])

    print C

    for row in cursor:

        if row[0] ==(count):

            cursor.deleteRow()

#INSERT CURSOR

import arcpy

# Create an insert cursor for a table specifying the fields that will have values provided

fields = ['FID', 'Shape', 'LineOID', 'Valie']

cursor = arcpy.da.InsertCursor('c:/W/S/pntp.shp', fields)

# Create 1 new row at top of the attribute table TO INSERT the feature PNTP2

for x in(0):

    cursor.insertRow((0, 0, 0, 0))

    # Delete cursor object

    del cursor

#UPDATE CURSOR

with arcpy.da.UpdateCursor("c:/W/S/pntp.shp",["FID"]) as cursor:

    FID += 1

0 Kudos
1 Solution

Accepted Solutions
JoshuaBixby
MVP Esteemed Contributor

The cursor is treating Valie as a string because it is just that, a string.  Overall, and especially since it looks like you are storing numbers as text, I encourage you to convert Valie from a string field to some form of numeric field.

Normally I would suggest using a CAST function within your ORDER BY clause, but I have never had success getting that to work with the sql_clause of ArcPy cursors.  From my read of the documentation, I am unclear whether it is supported only in subqueries for certain data formats or whether it is more generally supported.  If you find out or get it working, please share.

One final option that I know works with search cursors, but I don't know how it would behave with update cursors, is to use Python's built-in sorting methods.  Also, this could be a big performance bust on larger data sets.  In effect, you presort the cursor just before iterating over it:

cur = arcpy.da.SearchCursor(in_table, field_names)
i = #index of Valie field
for row in sorted(cur, key=lambda f: int(f)):
    print row

Overall, your life will be much much simpler if you can convert Valie to a numeric field or create a new field that is numeric to base your sorting/ordering upon.

View solution in original post

6 Replies
JoshuaBixby
MVP Esteemed Contributor

Can you explain why you are trying to do what you are trying to do?  Before diving into technical specifics, I think there are some logical issues that need to be sorted out first.  For example, what does inserting a new record at the "top" of the table get you?  For that matter, what do you mean by "top" of a table?

In SQL, the ordering of data isn't guaranteed unless you specify an ORDER BY clause.  Without using an ORDER BY clause, there are no guarantees that data will be retrieved in a certain, or even consistent, manner.  ArcGIS Desktop seems to present rows to the user ordered by ObjectID or FID, but I don't know if that is guaranteed.  Even if it is, it is an Esri-ism and not standard with SQL or DMBSes.

Looking at technical issues, what specifically are your error messages?  Specific error messages are helpful.

Regarding insert and update cursors, you can't manipulate the built-in unique identifier field, it is managed by the system.  Just think of the mayhem that could ensue if users could arbitrarily update a system generated and managed field.

KONPETROV
Occasional Contributor III

I need the inserted row to be the first row (at the top of the rows) for further procession, afterwards.

So The ORDER BY clause maube be useless?

For the last thing you wrote abour the cursors, would be better if i create a new field with the values i want?

Delete the post?

0 Kudos
JoshuaBixby
MVP Esteemed Contributor

If you need records processed in a certain order, don't use the system-generated and system-managed unique identifier field.  For one, the insert and update cursors don't allow users to directly manage/change those fields so you aren't going to be able to do what you want to do with those field.  Second, an insert cursor is more like appending to a list than inserting in a list because it doesn't allow you to specify where in the table the record will be inserted.  Which leads me to my third point, you are going to have to use an ORDER BY clause on your cursors with your newly created order-processing field.

KONPETROV
Occasional Contributor III

Ok i got it. The problem i have with ORDER BY in attribute table is that it understands the field Valie as strings and not as integers or numbers. As a result when i am trying it, i am getting

0

10

100

1000

1010

1020

...

1090

110

1100

1120

...

Why is that?

0 Kudos
JoshuaBixby
MVP Esteemed Contributor

The cursor is treating Valie as a string because it is just that, a string.  Overall, and especially since it looks like you are storing numbers as text, I encourage you to convert Valie from a string field to some form of numeric field.

Normally I would suggest using a CAST function within your ORDER BY clause, but I have never had success getting that to work with the sql_clause of ArcPy cursors.  From my read of the documentation, I am unclear whether it is supported only in subqueries for certain data formats or whether it is more generally supported.  If you find out or get it working, please share.

One final option that I know works with search cursors, but I don't know how it would behave with update cursors, is to use Python's built-in sorting methods.  Also, this could be a big performance bust on larger data sets.  In effect, you presort the cursor just before iterating over it:

cur = arcpy.da.SearchCursor(in_table, field_names)
i = #index of Valie field
for row in sorted(cur, key=lambda f: int(f)):
    print row

Overall, your life will be much much simpler if you can convert Valie to a numeric field or create a new field that is numeric to base your sorting/ordering upon.

KONPETROV
Occasional Contributor III

and of course you were right, i must sleep more maybe and also think fisrt the simple way.

0 Kudos