Retrieve a digit or string of digits from an integer field with ArcGIS Pro field calculator

3882
8
Jump to solution
02-09-2021 09:27 AM
YusefSamari
Occasional Contributor

I am using ArcGIS Pro 2.7.

I have a column of Easting values which each correspond to the bottom left corner of an OS UK grid square. I want to centre each value to be in the middle of whatever 1km grid square it intersects. The easting values are an integer field, each with a 6 digit number expressing how far the cell is from the origin of the OS UK grid.

To create my centred 1km square field, I want to take the first 3 digits of each easting value and replace the last 3 digits with '500'. So for example, 217890 would become 217500. I had thought to use !easting![0:3] in this part of the expression in Field Calculator, but it turns out that integer fields are not subscriptable. 

The somewhat laborious workaround I am using is to: 

1. Copy the easting values into a new text field as a string

2. Create a second new text field and populate that with the values from the new easting text field, replacing the last three characters with '500'.

3. Populate the centred easting, integer field with the values from the second text field.

There must be a way to do this in one go though - either to select digits from an integer field in Field Calculator, or replace specific digits from an integer field with another set of digits in Field Calculator? I haven't been able to find any examples of this, though.

Any insight much appreciated. Thanks!

0 Kudos
2 Solutions

Accepted Solutions
DavidPike
MVP Frequent Contributor

Hi, 

Using a python expression you can easily 'switch' between string and int data types (called type conversion I believe).

this is done using the str() and int() functions.

#returns a string
str(!easting!)[0:3] + '500'
#turns that string back to a number
int(str(!easting!)[0:3] + '500')

View solution in original post

jcarlson
MVP Esteemed Contributor

If you want to keep it as an integer data type, you can use integer division with some basic arithmetic.

values = [217890, 218330, 216540]

for v in values:
    print(f'{v} -> {v // 1000 * 1000 + 500}')

Returns:

217890 -> 217500
218330 -> 218500
216540 -> 216500

Integer division, the // operator, drops the remainder of the division. It's like the Abbott to modulo's Costello.

- Josh Carlson
Kendall County GIS

View solution in original post

8 Replies
DavidPike
MVP Frequent Contributor

Hi, 

Using a python expression you can easily 'switch' between string and int data types (called type conversion I believe).

this is done using the str() and int() functions.

#returns a string
str(!easting!)[0:3] + '500'
#turns that string back to a number
int(str(!easting!)[0:3] + '500')
YusefSamari
Occasional Contributor

Thanks! Unfortunately I'm still getting the same error message. Seems it still doesn't like the attempt to subscript an integer field, even with the string function.

YusefSamari_0-1612949044664.png

I don't know why Field Type is showing as 'TEXT' there - the 'test' field I created is definitely an integer field.

0 Kudos
DavidPike
MVP Frequent Contributor

You have the brackets/parentheses messed up - must be str(!Eastings!)

0 Kudos
YusefSamari
Occasional Contributor

Woops! Thanks, that's working now.

jcarlson
MVP Esteemed Contributor

If you want to keep it as an integer data type, you can use integer division with some basic arithmetic.

values = [217890, 218330, 216540]

for v in values:
    print(f'{v} -> {v // 1000 * 1000 + 500}')

Returns:

217890 -> 217500
218330 -> 218500
216540 -> 216500

Integer division, the // operator, drops the remainder of the division. It's like the Abbott to modulo's Costello.

- Josh Carlson
Kendall County GIS
DavidPike
MVP Frequent Contributor

never seen // before, nice!

0 Kudos
YusefSamari
Occasional Contributor

Lovely and very simple! This works fine, thanks!

0 Kudos
DanPatterson
MVP Esteemed Contributor

It is akin to "floor_divide"

values = np.array([217890, 218330, 216540])

np.floor_divide(values, 1000) * 1000 + 500

array([217500, 218500, 216500], dtype=int32)

Got to have a numpy example 😉


... sort of retired...