フィールド演算の Python の例

キーボードで値を入力する以外の方法でも、テーブル内の値を編集することができます。単一レコードまたはすべてのレコードのフィールド値を設定するために、数学的な計算を実行したい場合があります。すべてのレコードまたは選択したレコードについて、単純なものから高度なものまでさまざまな計算を実行することができます。さらに、属性テーブルのフィールドで、面積、長さ、周長、およびその他のジオメトリ プロパティを計算することもできます。以下の各セクションでは、フィールド演算を使用する例を示しています。Python、SQL、および Arcade を使用して計算が実行されます。

このトピックは、Python ベースの [フィールド演算 (Calculate Field)] の例に焦点を合わせます。Arcade 式の詳細については、ArcGIS Arcade のガイドをご参照ください。SQL 式の詳細については、「フィールドの計算」をご参照ください。

メモ:
  • Python では、インデントが構文の一部として見なされます。それぞれの論理レベルの定義には、2 つまたは 4 つのスペースを使用します。ステートメント ブロックの開始位置と終了位置を揃え、一貫性を保ってください。
  • Python の計算式フィールドは感嘆符 (!!) で囲みます。
  • 変数に名前を付けるときは、Python では大文字と小文字が区別されることに注意してください。つまり、「value」と「Value」は同じではありません。
  • ステートメントを入力した後でファイルに書き込むには、[エクスポート] ボタンをクリックします。[インポート] ボタンをクリックすると、既存の計算ファイルを検索して選択するためのプロンプトが表示されます。

簡単な演算

単純な文字列の例

文字列は、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]

最後から 2 つ目の文字

"d"

!fieldname![1:4]

2 つ目、3 つ目、4 つ目の文字

"bcd"

Python では、format() メソッドを使用した文字列の書式設定もサポートされています。

FieldA と FieldB をコロンで区切って結合します。

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

簡単な関数の例

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

乗算

!Rank! * 2

半径フィールドが指定された球体の体積を計算します。

4.0 / 3.0 * math.pi * !Radius! ** 3
レガシー:

ArcGIS Pro では Python 3 が使用され、ArcGIS Desktop では Python 2 が使用されます。Python 2 では整数の算術演算が使用されます。つまり、2 つの整数値を除算すると、必ず整数値が出力されます (3 / 2 = 1)。Python 3 では、2 つの整数値を除算すると、float 型が出力されます (3 / 2 = 1.5)。

組み込み Python 関数

Python では、maxminroundsum など、多数の組み込み関数を使用できます。

フィールドのリストの各レコードに対する最大値を計算します。

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

フィールドのリストの各レコードに対する最大値を計算します。

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

コード ブロックの使用

Python の条件式と [コード ブロック] パラメーターを使用すると、次のことが可能になります。

  • 任意の Python 関数の条件式での使用
  • ジオプロセシング機能およびオブジェクトへのアクセス
  • フィーチャ ジオメトリのプロパティへのアクセス
  • 新しいランダム値演算子へのアクセス
  • If...Then...Else 論理を使用した値の再分類

条件式の種類コード ブロック

Python 3

Python の機能がサポートされます。コード ブロックは、Python 関数 (def) を使用して表現されます。ジオメトリ プロパティは、必要に応じてポイント オブジェクトなどのジオプロセシング オブジェクトを使用して表現されます。

Arcade

Arcade の機能をサポートします。

SQL

SQL 式をサポートします。

SQL 式は、フィーチャ サービスおよびエンタープライズ ジオデータベースに対する計算を、特にパフォーマンスに関して適切にサポートするように実装されました。一度に 1 つのフィーチャまたは行を計算する代わりに、フィーチャ サービスまたはデータベースに 1 つのリクエストが設定されます。

レガシー:

ArcGIS Desktop[フィールド演算 (Calculate Field)] ツールでは、VBPYTHONPYTHON_9.3 が条件式の種類としてサポートされます。VB は、条件式の種類として一部の製品でサポートされていますが、ArcGIS Pro などの 64 ビット製品ではサポートされていません。

PYTHONPYTHON_9.3キーワードは、下位互換性のために ArcGIS Pro でまだサポートされていますが、選択肢として示されません。これらのキーワードを使用する Python スクリプトは引き続き動作します。

[Python 3] キーワードと従来の PYTHON_9.3 キーワードの間の違いは、[Python 3] が日付 フィールド内の値を Python の datetime オブジェクトとして返す点のみです。

メモ:

[Python 3] は、条件式の種類として、ArcGIS Pro とともにインストールされる Python のバージョンに関連していません。Python 3 は、単に歴史的に (PYTHON および PYTHON_9.3 の後の) 3 番目の Python 関連のキーワードということです。

Python 関数は、キーワード def の後に関数の名前と関数の入力引数を付けて定義します。Python 関数は、任意の数の入力引数 (引数がない場合も含む) を使って記述できます。値は、return ステートメントを使用して各関数から返されます。関数名は自由に作成できます (スペースを使用したり、名前の最初に数字を使用したりすることはできません)。

メモ:

return を使用して関数から明示的に値が返されない場合、この関数は None を返します。

メモ:

Python では、インデントが構文の一部として実行されることを忘れないでください。それぞれの論理レベルの定義には、4 つのスペースを使用します。ステートメント ブロックの開始位置と終了位置を揃え、一貫性を保ってください。

サンプル コード - 数学

メモ:

次のすべてのサンプル コードの使用では、条件式の種類が [Python 3] であることを前提とします。

フィールドの値を小数点以下第 2 位に四捨五入します。

条件式:
round(!area!, 2)

数学モジュールを使用して、メートルをフィートに変換します。変換した値を 2 乗し、さらに面積で乗算します。

条件式:
MetersToFeet((float(!shape.area!)))
コード ブロック:
import math
def MetersToFeet(area):
    return math.pow(3.2808, 2) * area

Python での論理を使用したフィールド演算

フィールドの値に基づいて分類します。

条件式:
Reclass(!WELL_YIELD!)
コード ブロック:
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

サンプル コード - ジオメトリ

メモ:

ジオメトリ単位の変換の詳細については、この後の「ジオメトリ単位の変換」をご参照ください。

フィーチャの面積を計算します。

条件式:
!shape.area!

フィーチャの最大 X 座標を計算します。

条件式:
!shape.extent.XMax!

フィーチャの頂点数を計算します。

条件式:
MySub(!shape!)
Code Block:
def MySub(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 だけシフトします。

条件式:
shiftXCoordinate(!SHAPE!)
Code Block:
def shiftXCoordinate(shape):
    shiftValue = 100
    point = shape.getPart(0)
    point.X += shiftValue
    return point

ジオメトリ単位の変換

ジオメトリ フィールドの面積および長さのプロパティは、@ 記号を付けて表現した単位の種類を使用して変更することができます。

  • 面積計測単位のキーワード:
    • ACRES | ARES | HECTARES | SQUARECENTIMETERS | SQUAREDECIMETERS | SQUAREINCHES | SQUAREFEET | SQUAREKILOMETERS | SQUAREMETERS | SQUAREMILES | SQUAREMILLIMETERS | SQUAREYARDS | SQUAREMAPUNITS | UNKNOWN
  • 長さ計測単位のキーワード:
    • CENTIMETERS | DECIMALDEGREES | DECIMETERS | FEET | INCHES | KILOMETERS | METERS | MILES | MILLIMETERS | NAUTICALMILES | POINTS | UNKNOWN | YARDS
メモ:

データが地理座標系で格納され、距離単位 (たとえば、フィート) が指定されている場合、長さの計算は測地線アルゴリズムを使用して変換されます。

注意:

地理座標系で表されるデータで面積単位を変換すると、グローブ全体で度 (10 進) が一定でないため、正確な結果となりません。

フィーチャの長さをヤード単位で計算します。

条件式:
!shape.length@yards!

フィーチャの面積をエーカー単位で計算します。

条件式:
!shape.area@acres!

geodesicArea の後に測定単位のキーワードが続く、geodesicLength および @ プロパティを使用して、測地線に基づく面積や長さも計算できます。

フィーチャの測地線の長さをヤード単位で計算します。

条件式:
!shape.geodesicLength@yards!

フィーチャの測地線の面積をエーカー単位で計算します。

条件式:
!shape.geodesicArea@acres!

サンプル コード - 日付

現在の日付を計算します。

条件式:
time.strftime("%d/%m/%Y")

現在の日付と時刻を計算します。

条件式:
datetime.datetime.now()

2000 年 12 月 31 になるように日付を計算します。

条件式:
datetime.datetime(2000, 12, 31)

現在の日付とフィールド内の値との間の日数を計算します。

条件式:
(datetime.datetime.now() - !field1!).days

フィールド内の日付の値に 100 日を加算して、日付を計算します。

条件式:
!field1! + datetime.timedelta(days=100)

フィールド内の日付の値の曜日 (Sunday (日曜) など) を計算します。

条件式:
!field1!.strftime('%A')

サンプル コード - 文字列

右端から 3 つ目の文字を返します。

条件式:
!SUB_REGION![-3:]

大文字の「P」をすべて小文字の「p」で置き換えます。

条件式:
!STATE_NAME!.replace("P","p")

2 つのフィールドを、スペースを区切り文字に使用して連結します。

条件式:
!SUB_REGION! + " " + !STATE_ABBR!

適切な大文字と小文字への変換

次の例は、すべての単語の最初の文字が大文字に、それ以外の文字が小文字になるように単語を変換するための異なる方法を示しています。

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

正規表現

Python re モジュールには正規表現のマッチング演算が用意されており、これを使用すると、文字列に対して複雑なパターン マッチングと置換ルールを実行できます。

文字列の末尾にある St または St. という単語を、Street という単語で置換します。

条件式:
update_street(!ADDRESS!)
コード ブロック:
import re
def update_street(street_name):
    return re.sub(r"""\b(St|St.)\Z""",  
                  'Street',
                  street_name)

累積計算と連続計算

特定の間隔に基づいて連続する ID または数値を計算します。

条件式:
autoIncrement()
コード ブロック:
rec=0
def autoIncrement():
    global rec
    pStart = 1 #adjust start value, if req'd 
    pInterval = 1 #adjust interval value, if req'd
    if (rec == 0): 
        rec = pStart 
    else: 
        rec = rec + pInterval 
    return rec

数値フィールドの累積値を計算します。

条件式:
accumulate(!FieldA!)
コード ブロック:
total = 0
def accumulate(increment):
    global total
    if total:
        total += increment
    else:
        total = increment
    return total

数値フィールドのパーセントの増分を計算します。

条件式:
percentIncrease(float(!FieldA!))
コード ブロック:
lastValue = 0
def percentIncrease(newValue):
    global lastValue
    if lastValue:
        percentage = ((newValue - lastValue) / lastValue)  * 100
    else: 
        percentage = 0
    lastValue = newValue
    return percentage

ランダム値

numpy サイトのパッケージを使用して、0.0 から 1.0 の間のランダムな浮動小数の値を計算します。

条件式:
getRandomValue()
コード ブロック:
import numpy
def getRandomValue():
    return numpy.random.random()

ランダム モジュールを使用して、0 から 10 の間のランダムな整数を計算します。

条件式:
random.randint(0, 10)
コード ブロック:
import random

NULL 値の計算

Python 式では、Python の None を使用して NULL 値を計算できます。

メモ:

次の計算は、フィールドに NULL 値が許可されている場合のみ機能します。

Python None を使用した NULL 値の計算

条件式:
None

関連トピック