简体   繁体   English

使用 ArcGIS Pro 在 Field Calculator 中定位子字符串

[英]Locating a substring in Field Calculator using ArcGIS Pro

I have what should be a fairly straightforward operation failing in ArcGIS Pro 2.4, and cannot for the life of me work out why.我在 ArcGIS Pro 2.4 中有一个相当简单的操作失败了,但我终其一生都无法弄清楚原因。

If the field "assettype" contains a portion of the search string, then set the value of assettype_groupup to the value I return.如果字段“assettype”包含搜索字符串的一部分,则将 assettype_groupup 的值设置为我返回的值。

Eg, if "assetttype" contains the string "Building |Residential |Large ", and I test whether it contains the term "Residential", and that evaluates to true, then return the string "Residential".例如,如果“assetttype”包含字符串“Building |Residential |Large”,并且我测试它是否包含术语“Residential”,并且计算结果为真,则返回字符串“Residential”。

Currently the code does not seem to be returning any result / has no effect, and appears to run too quickly (2-3 seconds for 3,000,000 lines).目前代码似乎没有返回任何结果/没有效果,并且似乎运行得太快(3,000,000 行 2-3 秒)。

If I try a ternary statement, which means using a single term at a time, it seems to work just fine.如果我尝试使用三元语句,这意味着一次使用一个术语,它似乎工作得很好。 I'd rather not take this approach as the if/elif possibilities could wind up being extensive in nature and I'd like to run the routine only once.我宁愿不采用这种方法,因为 if/elif 的可能性在本质上可能会很广泛,而且我只想运行一次例程。

Can you see any obvious issues with the setup below你能看到下面的设置有什么明显的问题吗

#Target Field Name 
assettype_groupup

#Expression
func(!assettype!)

# Code block
def func(input):
    if 'Residential' in input:
        return 'Residential'
    elif 'Industrial/Utilities' in input:
        return 'Industrial/Utilities'
    elif 'Transport/Infrastructure' in input:
        return 'Transport/Infrastructure'
    elif 'Conservation/National Park' in input:
        return 'Conservation/National Park'
    elif 'Recreational/Open Space' in input:
        return 'Recreational/Open Space'
    elif 'Mixed Use' in input:
        return 'Mixed Use'
    elif 'Community Use' in input:
        return 'Community Use'
    elif 'Rural/Primary Production' in input:
        return 'Rural/Primary Production'
    elif 'Special Use' in input:
        return 'Special Use'
    elif 'Unknown' in input:
        return 'Unknown'
    else:
        ''

I am not familiar with ArcGIS Pro, but do know Python fairly well.我不熟悉 ArcGIS Pro,但对 Python 相当了解。

In Python you should avoid naming variables or arguments the same as any built-ins, and input() is the name of a built-in function.在 Python 中,您应该避免将变量或参数命名为任何内置函数,而input()是内置函数的名称。 Also, the line after the final else: , should be return '' .此外,最后的else:之后的行应该是return '' Since that's not the case, your function will effectively return None when there are no matches, not the empty string '' (assuming that's what you intended).由于情况并非如此,当没有匹配项时,您的函数将有效地返回None而不是空字符串'' (假设这是您的意图)。

With that in mind, the following would be a better way to write the function that would avoid both of the issues mentioned above:考虑到这一点,以下将是编写避免上述两个问题的函数的更好方法:

TARGETS = (
    'Residential',
    'Industrial/Utilities',
    'Transport/Infrastructure',
    'Conservation/National Park',
    'Recreational/Open Space',
    'Mixed Use',
    'Community Use',
    'Rural/Primary Production',
    'Special Use',
    'Unknown',
)


# Code block
def func(info):
    for target in TARGETS:
        if target in info:
            return target
    else:  # Nothing matched.
        return ''

A more advanced, slightly shorter and likely much faster, way to do would be by using Python's re regular expression module which is part of its standard library:一种更高级、更短且可能更快的方法是使用 Python 的re正则表达式模块,它是其标准库的一部分:

import re

regex = re.compile('|'.join(map(re.escape, TARGETS)))

# Code block
def func(info):
    mo = regex.search(info)
    return mo.group(0) if mo else ''

In Python 3.8.0+ it could be shortened a little bit more by taking advantage of PEP 572's new syntax for assignment expressions using := (aka the "walrus" operator) which was added beginning in that version:在 Python 3.8.0+ 中,可以通过利用PEP 572使用:= (又名“海象”运算符)的赋值表达式新语法将它缩短一点,该语法从该版本开始添加:

import re

regex = re.compile('|'.join(map(re.escape, TARGETS)))

def func(info):
    return mo.group(0) if (mo := regex.search(info)) else ''  # Py 3.8.0+

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM