计算字段 Python 示例

使用键盘输入值并不是编辑表中值的唯一方式。 要针对单个记录甚至是所有记录的一组字段值执行数学计算。 您可以对所有记录或选中记录执行简单计算和高级计算。 此外,还可以在属性表中的字段上计算面积、长度、周长和其他几何属性。 以下各部分包括使用字段计算器的若干示例。 使用 Python、SQL 和 Arcade 执行计算。

本主题着重于基于 Python计算字段示例。 要了解有关 Arcade 表达式的详细信息,请参阅 ArcGIS Arcade 指南。 要了解有关 SQL 表达式的详细信息,请参阅计算字段值。 要了解有关 VBScript 示例的详细信息,请参阅计算字段 VBScript 示例

注:
  • Python 强制将缩进作为语法的一部分。 请使用两个或四个空格来定义每个逻辑级别。 将语句块的开头和结尾对齐并且保持一致。
  • Python 计算表达式字段将使用惊叹号 (!!) 括起。
  • 命名变量时,请注意 Python 区分大小写,因此 value 不同于 Value
  • 输入语句后,如果想将其写入文件,请单击导出按钮 导出导入按钮 Import 将提示您查找和选择一个现有的计算文件。

简单计算

仅通过一个短表达式就可以计算出多种计算结果。

简单字符串示例

一系列 Python 字符串函数均支持使用字符串,包括 capitalizerstripreplace

CITY_NAME 字段中字符串的首字母大写。

!CITY_NAME!.capitalize()

移除 CITY_NAME 字段中自字符串结尾起的所有空白区。

!CITY_NAME!.rstrip()

STATE_NAME 字段中的“california”全部替换为“California”。

!STATE_NAME!.replace("california", "California")

Python 中,字符串字段中的字符可以通过索引和分割操作进行访问。 索引操作将在索引位置提取字符,而分割操作则会提取一组字符。 在下表中,假设 !fieldname! 是值为 "abcde" 的字符串字段:

示例说明结果

!fieldname![0]

第一个字符

"a"

!fieldname![-2]

倒数第二个字符

"d"

!fieldname![1:4]

第二、三和四个字符

"bcd"

Python 也支持使用 format() 方法的字符串格式。

将合并后的 FieldA 和 FieldB 以冒号分隔开。

"{}:{}".format(!FieldA!, !FieldB!)

简单数学示例

Python 提供了处理数字的工具。 Python 也支持一些数值和数学函数,包括 mathcmathdecimalrandomitertoolsfunctoolsoperator

运算符说明示例结果

x + y

x 加上 y

1.5 + 2.5

4.0

x - y

x 减去 y

3.3 - 2.2

1.1

x * y

x 乘以 y

2.0 * 2.2

4.4

x / y

x 除以 y

4.0 / 1.25

3.2

x // y

x 除以 y(向下取整除法)

4.0 // 1.25

3.0

x % y

x 模 y

8 % 3

2

-x

x 的负数表达式

x = 5

-x

-5

+x

x 不变

x = 5

+x

5

x ** y

以 x 为底,以 y 为指数的幂

2 ** 3

8

将一个字段的值乘以 2。

!Rank! * 2

根据给定的半径字段计算球体的体积。

4.0 / 3.0 * math.pi * !Radius! ** 3
注:

短整型、长整型和大整型字段在它们支持的整数范围上有所不同:

  • 短整型(16位整数)- 支持从 -(215) 到 215(-32,768 到 32,767)的整数。
  • 长整型(32 位整数)- 支持从 -(231) 到 231(-2,147,483,648 到 2,147,483,647)的整数。
  • 大整型(64 位整数)- 支持从 -(253) 到 253(-9,007,199,254,740,992 到 9,007,199,254,740,991)的整数。

旧版本:

ArcGIS Pro 中,使用的是 Python 3,在 ArcGIS Desktop 中,使用的是 Python 2。 Python 2 使用的是整型数学计算,这就意味着两个整型值相除将始终生成整型值 (3 / 2 = 1)。 在 Python 3 中,两个整型值相除将生成浮点型值 (3 / 2 = 1.5)。

Python 内置函数

Python 包含多个内置函数,包括 maxminroundsum

从字段列表中计算每个记录的最大值。

Expression:
max([!field1!, !field2!, !field3!])

从字段列表中计算每个记录的总和。

Expression:
sum([!field1!, !field2!, !field3!])

使用代码块

通过 Python 表达式和代码块参数可执行以下操作:

  • 在表达式中应用任意 Python 函数。
  • 访问地理处理函数和对象。
  • 访问要素几何的属性。
  • 访问新的随机值运算符。
  • 使用 if-then-else 逻辑对值进行重分类。

表达式类型代码块

PythonPYTHON3 关键字)

支持 Python 函数。 使用 Python 函数 (def) 表示代码块。 适当时,使用地理处理对象(如点对象)表示几何属性。

Arcade

支持 Arcade 函数。

SQL

支持 SQL 表达式。

执行 SQL 表达式可以更好地支持使用要素服务和企业级地理数据库的计算,尤其是在性能方面。 使用该表达式可以将单次请求设置为要素服务或数据库,而不必一次执行一个要素或一行的计算。

VBScript

支持 VBScript 函数。

旧版本:

ArcGIS Pro 中,向后兼容性仍支持 PYTHONPYTHON_9.3 关键字,但是不作为选择列出。 使用这些关键字的 Python 脚本将可继续使用。

PYTHON3 表达式类型与旧版 PYTHON_9.3 关键字的唯一区别在于 PYTHON3 会将日期字段中的值作为 Python datetime 对象返回。

注:

PYTHON3 表达式类型与随 ArcGIS Pro 安装的 Python 版本无关。 它是历史上的第三个 Python 相关关键字(在现在隐藏 PYTHONPYTHON_9.3 关键字之后)。

Python 函数可通过 def 关键字定义,关键字后为函数名称及函数的输入参数。 可编写 Python 函数,以接受任何数量的输入参数(也可以没有任何参数)。 函数将通过 return 语句返回值。 函数名称可由您自行选取(不得使用空格,也不得以数字开头)。

注:

如果函数未通过 return 语句显式返回值,则函数将返回 None

注:

Python 强制将缩进作为语法的一部分。 请使用四个空格来定义每个逻辑级别。 将语句块的开头和结尾对齐并且保持一致。

代码示例 - 数学

可以使用表达式参数添加简单的数学表达式,并可以使用表达式代码块参数构建更复杂的示例。

将字段的值四舍五入为保留两位小数。

Expression:
round(!area!, 2)

通过 math 模块将米转换成英尺。 以转换值为底,以 2 为指数进行幂运算,然后再乘以 area。

Expression:
MetersToFeet((float(!shape.area!)))

Code Block:
import math
def MetersToFeet(area):
    return math.pow(3.2808, 2) * area

通过 Python 逻辑计算字段

可以使用 ifelseelif 语句将逻辑模式包含在代码块中。

按照字段值进行分类。

Expression:
Reclass(!WELL_YIELD!)

Code Block:
def Reclass(WellYield):
    if (WellYield >= 0 and WellYield <= 10):
        return 1
    elif (WellYield > 10 and WellYield <= 20):
        return 2
    elif (WellYield > 20 and WellYield <= 30):
        return 3
    elif (WellYield > 30):
        return 4

代码实例 - 几何

除以下代码示例外,请参阅下方的“几何单位转换”部分,以了解有关转换几何单位的详细信息。

计算某要素的面积。

Expression:
!shape.area!

计算某要素的最大 x 坐标。

Expression:
!shape.extent.XMax!

计算某要素中的折点数。

Expression:
getVertexCount(!shape!)

Code Block:
def getVertexCount(feat):    
    partnum = 0

    # Count the number of points in the current multipart feature
    partcount = feat.partCount
    pntcount = 0

    # Enter while loop for each part in the feature (if a singlepart 
    # feature, this will occur only once)
    while partnum < partcount:
        part = feat.getPart(partnum)
        pnt = part.next()

        # Enter while loop for each vertex
        while pnt:
            pntcount += 1   
            pnt = part.next()
   
            # If pnt is null, either the part is finished or there 
            # is an interior ring
            if not pnt: 
                pnt = part.next()
        partnum += 1
    return pntcount

将点要素类中每个点的 x 坐标平移 100。

Expression:
shiftXCoordinate(!SHAPE!)

Code Block:
def shiftXCoordinate(shape):
    shiftValue = 100
    point = shape.getPart(0)
    point.X += shiftValue
    return point

几何单位转换

可以使用 getAreagetLength 几何方法修改几何字段的面积和长度属性。

了解有关地理处理中受支持的线性和面积单位的详细信息

有关详细信息,请参阅 PolygonPolyline 对象。

警告:

转换地理坐标系中数据的面积单位会生成不正确的结果,这是由于沿 globe 的十进制度并不一致。

计算某要素的长度(以码为单位)。

Expression:
!shape!.getLength('PLANAR', 'YARDS')

计算某要素的面积(以英亩为单位)。

Expression:
!shape!.getArea('PLANAR', 'ACRES')

测地线面积和长度也可以使用 GEODESIC 方法类型进行计算。

有关详细信息,请参阅 PolygonPolyline 对象。

了解有关地理处理工具以及线性和面积单位的详细信息

计算某要素的测地线长度(以码为单位)。

Expression:
!shape!.getLength('GEODESIC', 'YARDS')

计算某要素的测地线面积(以英亩为单位)。

Expression:
!shape!.getArea('GEODESIC', 'ACRES')

代码示例 - 日期字段

日期和时间可使用 datetimetime 模块进行计算。

注:

要在字段类型之间传递时间值(日期、仅日期、仅时间、时间戳偏移和文本),改用转换时间字段工具。

计算当前日期。

Expression:
time.strftime("%d/%m/%Y")

计算当前日期和时间。

Expression:
datetime.datetime.now()

计算当前日期。

Expression:
datetime.date.today()

计算日期为 2015 年 3 月 15 日下午 1:30:00。

Expression:
datetime.datetime(year=2015, month=3, day=15, hour=13, minute=30, second=0)

计算当前日期和字段中的值之间的天数。

Expression:
datetime.datetime.now().day - !OID!

通过向字段中的日期值添加 100 天来计算日期。

Expression:
!field1! + timedelta(days=100)

Code Block:
from datetime import timedelta

使用 datetime 模块中的 ctime 方法计算代表日期的字符串。 该示例将创建一个字符串,其格式为:'Mon Feb 22 10:15:00 2021'

Expression:
!field1!.ctime()

计算字段中的日期值为一周中的周几(例如,星期天)。

Expression:
!field1!.strftime('%A')

使用 datetime 模块的 strftime 方法和显式格式字符串,从日期字段计算格式字符串。 该示例将创建一个字符串,其格式为:'02/22/2021, 10:15:00'

Expression:
!field1!.strftime("%m/%d/%Y, %H:%M:%S")

使用 ISO 8601 格式的字符串计算日期。

Expression:
'1969-07-21 02:56:00'

使用月、日、年、时间约定计算日期。

Expression:
'July 1 2020 12:30:45'

代码示例 - 仅时间字段

使用 datetime 模块的 time 函数计算时间为下午 4:30:00。

Expression:
time(hour=16, minute=30, second=0)

Code Block:
from datetime import time

将日期字段计算为仅时间字段,将仅应用 datetime 对象的时间部分。

Expression:
!date_field!

代码示例 - 仅日期字段

注:

要在字段类型之间传递时间值(日期、仅日期、仅时间、时间戳偏移和文本),改用转换时间字段工具。

计算的日期为 2000 年 12 月 31 日。

Expression:
datetime(2000, 12, 31)

将日期字段计算为仅时间字段,将仅应用 datetime 对象的时间部分。

Expression:
!date_field!

代码示例 - 时间戳偏移字段

注:

要在字段类型之间传递时间值(日期、仅日期、仅时间、时间戳偏移和文本),改用转换时间字段工具。

使用 datetime.timezone 模块的 utc 属性将 UTC 时间戳偏移添加到当前日期和时间。

Expression:
datetime.now(tz=timezone.utc)

Code Block:
from datetime import timezone

使用 zoneinfo 模块的 ZoneInfo 类将时间戳偏移添加到当前日期和时间以设置时区。

Expression:
datetime.now(ZoneInfo('America/New_York'))

Code Block:
from zoneinfo import ZoneInfo

代码实例 - 字符串

可以使用多种 Python 编码模式来完成字符串计算。

返回最右侧三个字符。

Expression:
!SUB_REGION![-3:]

将所有大写字母 P 替换为小写字母 p。

Expression:
!STATE_NAME!.replace("P","p")

使用空格分隔符连接两个字段。

Expression:
!SUB_REGION! + " " + !STATE_ABBR!

转换为正确的大小写形式

下列各例显示的是转换单词的不同方法,这些方法可使每个单词的首字母变为大写、其余字母变为小写。

Expression:
' '.join([i.capitalize() for i in !STATE_NAME!.split(' ')])
Expression:
!STATE_NAME!.title()

正则表达式

Python re 模块提供了正则表达式匹配操作,可用于对字符串执行复杂的模式匹配和替换规则。

使用单词 Street 替换 St 或 St.,在字符串的末尾生成一个新单词。

Expression:
update_street(!ADDRESS!)

Code Block:
import re
def update_street(street_name):
    return re.sub(r"""\b(St|St.)\Z""",  
                  'Street',
                  street_name)

累加计算和顺序计算

可以使用全局变量来进行累加计算和顺序计算。

根据某间隔值计算顺序 ID 或数字。

Expression:
autoIncrement(10, 5)

Code Block:
rec = 0
def autoIncrement(start=1, interval=1):
    global rec
    if rec == 0:
        rec = start
    else:
        rec += interval
    return rec

计算数值型字段的累加值。

Expression:
accumulate(!FieldA!)

Code Block:
total = 0
def accumulate(increment):
    global total
    if total:
        total += increment
    else:
        total = increment
    return total

计算数值型字段的百分比增量。

Expression:
percentIncrease(float(!FieldA!))

Code Block:
lastValue = 0
def percentIncrease(newValue):
    global lastValue
    if lastValue:
        percentage = ((newValue - lastValue) / lastValue)  * 100
    else: 
        percentage = 0
    lastValue = newValue
    return percentage

随机值

可以使用 random 模块来计算随机值。

通过 numpy 站点包来计算 0.0 和 1.0 之间的随机浮点值。

Expression:
getRandomValue()

Code Block:
import numpy

def getRandomValue():
    return numpy.random.random()

使用 random 模块来计算 0 与 10 之间的随机整数。

Expression:
random.randint(0, 10)

Code Block:
import random

计算空值

Python 表达式中,可通过 Python None 来计算空值。

注:

仅当字段可为空时,以下计算才适用。

使用 Python None 计算空值。

Expression:
None

相关主题