Select to view content in your preferred language

NumPy and Arcpy play nice

769
0
11-23-2021 04:46 PM
Labels (1)
DanPatterson
MVP Esteemed Contributor
4 0 769

Create a table for use in Pro.

 

from arcpy.da import NumPyArrayToTable
ids = np.arange(0, 250000)
dt = [("ID_s", 'int32'), ("Rand_Ints", 'int32')]
arr = np.zeros((250000, ), dtype=dt)  # note the shape
arr["ID_s"] = ids
arr["Rand_Ints"] = nums
NumPyArrayToTable(arr, gdb + "\\A250K")
#
arr[:3]  # first 3 records
array([(0, 241), (1, 542), (2, 488)],
      dtype=[('ID_s', '<i4'), ('Rand_Ints', '<i4')])

 

Pretend you want to do some "stuff" and "join" the results to the table.

 

from arcpy.da import TableToNumPyArray, ExtendTable

in_arr = TableToNumPyArray(
    gdb + "\\A250K",
    field_names=['ID_s', 'Rand_Ints'],
    where_clause=None,
    skip_nulls=False,
    null_value=None
)

in_arr.shape
(250000,)

in_arr[:3]
array([(0, 241), (1, 542), (2, 488)],
      dtype=[('ID_s', '<i4'), ('Rand_Ints', '<i4')])

# timeit results on my machine
%timeit TableToNumPyArray(gdb + "\\A250K", field_names=['ID_s', 'Rand_Ints'], where_clause=None, skip_nulls=False, null_value=None)

83.1 ms ± 1.52 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)

 

Do a simple calculation and send the results back (everyone loves a standard deviation)

 

vals = in_arr['Rand_Ints']

vals[:3]
array([241, 542, 488])

mean_ = np.mean(vals)
stdev = (vals - mean_) / mean_

 

Now there are several places you can go now... How about a new table with the results???

 

from numpy.lib.recfunctions import append_fields
# reference : https://numpy.org/doc/stable/user/basics.rec.html
out_arr = append_fields(
    in_arr, "std_dev", stdev, fill_value=-1, usemask=False, asrecarray=False)

out_arr.dtype
dtype([('ID_s', '<i4'), ('Rand_Ints', '<i4'), ('std_dev', '<f8')])

NumPyArrayToTable(out_arr, gdb + "\\A250K_std")  # out it goes

 

 

out_tbl.png

You can extend an existing table if you want, with a slightly different process, but the results are the same.  My preference is a new table, since the old one is intact and can be readily be deleted.

 

Addendum

 

# save as numpy
np.save(r"C:\Arc_projects\Test_29\A250K_arr.npy",out_arr)
# bring it back
back_in = np.load(r"C:\Arc_projects\Test_29\A250K_arr.npy")

back_in.dtype
dtype([('ID_s', '<i4'), ('Rand_Ints', '<i4'), ('std_dev', '<f8')])

back_in[:3]
array([(0, 241, -0.51813616), (1, 542,  0.08369377),
       (2, 488, -0.02427572)],
      dtype=[('ID_s', '<i4'), ('Rand_Ints', '<i4'), ('std_dev', '<f8')])

 

You can save your work as numpy arrays and even bring them back should you want a backup that can be read without ArcGIS Pro (like.... who doesn't!!!)

 

About the Author
Retired Geomatics Instructor (also DanPatterson_Retired). Currently working on geometry projects (various) as they relate to GIS and spatial analysis. I use NumPy, python and kin and interface with ArcGIS Pro.
Labels