Rounding issues using Python in ArcGIS Pro

4330
12
Jump to solution
02-05-2018 08:38 AM
AdrianWelsh
MVP Notable Contributor

It seems to me that ArcGIS Pro is not rounding my numbers correctly when I use Python in Calculate Field. Or my expression is incorrect.

Here is my example:

The Shape_Area of a feature is 7464.72748

My Calculate Field expression is

str(int(round(round(!Shape_Area!), -1)))

I would think this should result in a string value of 7470, but it gave me 7460.

Where am I going wrong? Shouldn't round(7464.72748) give me 7465 more or less?

And then round(7465, -1) give me 7470?

0 Kudos
1 Solution

Accepted Solutions
DanPatterson_Retired
MVP Esteemed Contributor

dozens of ways.... time to explore, this will get you going.

import math  # which is available in arcmap and the field calculator
math.ceil(2725.059761)
2726

int(math.ceil(2725.059761 / 10.0)) * 10
2730

# or if you understand base 9 and base 10 differences

(2725.059761+9)//10 *10
2730.0

plus some numpy stuff.... the rest are tricks etc

Excel makes people dependent on masking the tricks that us old timers relied upon for years.

View solution in original post

12 Replies
DanPatterson_Retired
MVP Esteemed Contributor

You are now in python 3... did you see the docs first? It works as expected

https://docs.python.org/3/library/functions.html#round

a = 7464.72748

round(a, 1)
7464.7

round(a, 0)
7465.0

round(a, -1)
7460.0‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍

skip the round round round thing, that will get confusing

AdrianWelsh
MVP Notable Contributor

I was wondering if Python 3 had anything to do with it since when I carried out the expression in Python 2, it worked as expected.

So, to get this straight, Python no longer rounds like normal arithmetic (like Excel would do). It rounds to the nearest even number first, unless it's far down the decimal chain, then it's "surprising" as the text puts it.

The round round was due to having to join up a table in Excel that had already rounded once - it's complicated but worked better than just one round.

So, is there way to round like Excel rounds?

For another example, when Shape_Area is 2725.059761, how do I make it round to 2730 versus 2720 (like I would in Excel and normal arithmetic)?

DanPatterson_Retired
MVP Esteemed Contributor

dozens of ways.... time to explore, this will get you going.

import math  # which is available in arcmap and the field calculator
math.ceil(2725.059761)
2726

int(math.ceil(2725.059761 / 10.0)) * 10
2730

# or if you understand base 9 and base 10 differences

(2725.059761+9)//10 *10
2730.0

plus some numpy stuff.... the rest are tricks etc

Excel makes people dependent on masking the tricks that us old timers relied upon for years.

AdrianWelsh
MVP Notable Contributor

Wow, this is good stuff to explore. I'm not sure I want to use the ceiling function since I don't always want it to round up. 

But, since this is really only for joining tables together to make a simple match, I can force excel to do the same. It looks like the function is this:

=CEILING.MATH(2725.059761,10) results in 2730

Base 9 and 10?!? That's a thinker. I'll play around with that some... until my head hurts!

0 Kudos
DanPatterson_Retired
MVP Esteemed Contributor

Adrian.... math.floor ...   homework...

besides everyone rounds to the nearest 10ish

step outside the box... go all 8's

int(math.ceil(2725.059761 / 8.0)) * 8
2728

Or make it whatever you want

a = np.array([110.1567])

np.clip(a, 108, 109)
 array([ 109.])
JoshuaBixby
MVP Esteemed Contributor

What’s New In Python 3.0 — Python 3.6.4 documentation :

  • The round() function rounding strategy and return type have changed. Exact halfway cases are now rounded to the nearest even result instead of away from zero. (For example, round(2.5) now returns 2 rather than 3.) round(x[, n]) now delegates to x.__round__() instead of always returning a float. It generally returns an integer when called with a single argument and a value of the same type as x when called with two arguments.
0 Kudos
DanPatterson_Retired
MVP Esteemed Contributor

we are using 3.6 in PRO, my test environment

0 Kudos
JoshuaBixby
MVP Esteemed Contributor

Not sure on your comment.  Pro 2.1 does come with Python 3.6, I don't think anyone is disagreeing with that.

0 Kudos
DanPatterson_Retired
MVP Esteemed Contributor

Yes... python 3.6 is distributed with PRO. 

It was more to show people that the python 3.6 docs should be read and soon if they are going to be using PRO.

Besides, there are so many other ways options for 'rounding' that are available and most people haven't seen them.

0 Kudos