フィールドがフィーチャクラスに存在するかどうかを検索します


8

数十のフィーチャクラスがあり、そのうちの1つに探しているフィールドが含まれています。それらはいくつかの異なるファイルジオデータベースに格納されます。

各フィーチャクラスを検索して、自分のフィールドを持つフィーチャクラスをすばやく見つける方法はありますか?それとも、カタログでそれぞれの属性テーブルを確認する必要がありますか?一部のファイルは同じ名前ですが、別の場所に保存されています。

Calculate ValueModelBuilderのツール内でこれを実行できるようにしたいので、必要になるたびに単一のファイルgdbでモデルを実行し、そのgdb内のすべてのフィーチャクラスを検索してフィールドを探します。 。

これまでのところ、gdbファイル内のすべての機能クラスを再帰的に反復する機能クラスイテレータがあります。内部Calculate Valueには、次のコードがあります。

findField(r"%Feature%", "%Search Field%")

def findField(fc, fi):
  lst = arcpy.ListFields(fc)
  for f in lst:
    if f.name == fi:
      return fc
    else:
      return "not found"

戻り値はOutput Values文字列として収集されます。フィールドが少なくとも4つに存在するにもかかわらず、すべてのフィーチャクラスの出力は「見つかりません」でした。 ここに画像の説明を入力してください


あなたは何の価値を計算しようとしていますか?テーブルにレコードを挿入しようとしていますか?値計算ツールを何に使用しようとしているのかはあまり意味がありません...
RyanKDalton

Calculate Valueフィールドを検索し、フィールドが見つかった場合はフィーチャクラスのパスを文字列として返すために、内部にPythonコードを挿入しました-以下の私の回答を参照してください。
Cindy Jayakumar

回答:


4

私は文字列操作(受け入れられた回答のような)ではなくリスト内包を好みます。私の意見では、これはより読みやすく、pythonicです。さらに、(str.lower()@ RyanDaltonのように)機能を非常に簡単に追加することで、リストを理解するアプローチを拡張できます。

def findField(fc, fi):
  fieldnames = [field.name for field in arcpy.ListFields(fc)]
  if fi in fieldnames:
    return "found in " +fc
  else:
    return "not found in " +fc

ワンライナーif-elseステートメントを使用する場合:

def findField(fc, fi):
  fieldnames = [field.name for field in arcpy.ListFields(fc)]
  return "found in " + fc if fi in fieldnames else "not found in " + fc

またはもっと短くても読みにくい:

    def findField(fc, fi):
      return "found in " + fc if fi in [field.name for field in arcpy.ListFields(fc)] else "not found in " + fc

はい、これは今のところ望ましい答えです。ずっと前にこの質問をしましたが、ビットとピースをハッキングする代わりに完全にPythonに切り替える前にModelBuilderで無駄にした9か月を覚えるのは苦痛です。
Cindy Jayakumar

19

フィールドが存在するかどうかをテストするには、Bjorn Kuiperによる次の関数を確認してください。

def FieldExist(featureclass, fieldname):
    fieldList = arcpy.ListFields(featureclass, fieldname)

    fieldCount = len(fieldList)

    if (fieldCount == 1):
        return True
    else:
        return False

次の使用例で:

    if (not FieldExist(myFeatureClass, "myField")):
      arcpy.AddError("Field 'myField' does not exist in " + myFeatureClass)
      sys.exit()

しばらく前に似たようなものを使用していましたが、探していた出力が得られませんでした。
Cindy Jayakumar

12

あなたはarcpyを使うことができます:

import arcpy

myField = "test"

env.workspace = "D:/test/data.gdb"
fcs = arcpy.ListFeatureClasses()

for f in fcs:
    fieldList = arcpy.ListFields(f)
    for field in fieldList:   
         if field.name == myField:
             print f

これのほかに、ドライブ内のファイルにos.walkを使用できます。

path = r"C:"
for root, dirs, files in os.walk(path):
    for fileName in files:
            .........

お役に立てば幸いです...


私はそれを試しました、そしてコードは理にかなっていますが、それは何もしません。私は4つのフィーチャクラスにあるフィールドを使用してテストしました。スクリプトは実行されましたが、何も出力されませんでした。
Cindy Jayakumar

ああすみません、フィールドセットのフィールドをループするのを忘れて、今答えを更新してテストしました。
アラゴン

更新されたコードを試してみましたが、実行されましたが、フィールドがジオデータベース内のいくつかのフィーチャクラスにあるにもかかわらず、出力がありません。
Cindy Jayakumar

3

アラベラ、あなたの特徴クラスは特徴データセットにありますか?その場合、フィーチャデータセットをウォークスルーしてフィーチャクラスを確認する必要があるため、@ Aragonのソリューションは機能しません。

@Aragonのコードと、GDBのすべてのフィーチャクラスのリスト(フィーチャデータセット内を含む)の @gotchulaのコードを使用して、ジオデータベース内のすべてのフィーチャデータセットとフィーチャクラスを読み取る次のコードを生成しました。

:デフォルトでは、ListFieldsは大文字と小文字を区別するように見えます。大文字と小文字を区別しない検索のために、ユーザー定義フィールド名とListField名の両方を小文字に変換するコードを追加しました。ほとんどの印刷ステートメントを無効にすることもできますが、コードを実行しながら追跡できるように、それらはそのままにしておきます。また、サブ関数FindFieldを内に作成したので、再コーディングすることなく、スクリプト内で複数回呼び出すことができます。

import arcpy

def FindField(fc,myField):
    fieldList = arcpy.ListFields(fc)
    for field in fieldList:
        if str.lower(str(field.name)) == str.lower(myField):
            print "    " + fc + " contains fieldname: " + myField

myField = "test"
arcpy.env.workspace = "D:/test/data.gdb"

#Search root level featureclasses
for fc in arcpy.ListFeatureClasses():
    print "Searching root level Featureclasses..."
    print "  Searching " + fc
    FindField(fc,myField)

#Search Feature Datasets
for fds in arcpy.ListDatasets('','feature'):
    print "Searching FeatureDataset: " + fds

    for fc in arcpy.ListFeatureClasses('','',fds):
        print "  Searching Featureclass... " + fc
        FindField(fc,myField)

これをモデルで実行するので、少し調整してテストしました。何をCalculate Value返して欲しいのかわからない-でもいいreturn "true" if FindField(fc,myField) =="true" else "false"
Cindy Jayakumar

ああ、ちょうど私の前のコメントは何も教えてくれないことに気づきました。また、モデル内でそのブールテストを実行しても何も返されません。
Cindy Jayakumar

計算値?ブールテスト?私はあなたが何を求めているのかについてのあなたの質問を明確にするべきだと思います。
RyanKDalton 2012年

質問を編集しました。
Cindy Jayakumar 2012年

2

何人かは私がこれを行う方法で踊りましたが、これを行う簡単な1行の方法を追加したいだけです。

if 'fieldname' in [f.name for f in arcpy.ListFields(fc)]:
    ## do something.

(多くのフィーチャクラスを反復処理する場合)より便利なものは何ですか?上記の反対をフィルターとして使用します。

for fc in arcpy.ListFeatureClasses():
    if not 'fieldname' in [f.name for f in arcpy.ListFields(fc)]:
        continue
    ## now do something with the feature class.

1

この質問への回答で、コードの助けを借りて回答を見つけました。すべてのフィールド名を取得して文字列に変換し、その文字列でフィールドを検索しました。Calculate Value現在のコードは次のようになります。

def findField(fc, fi):
  fieldList = arcpy.ListFields(fc)
  nameList = []
  for f in fieldList:
    nameList.append(f.name)
  str_lst = "!" + "!, !".join(nameList) + "!"
  return "found in" +fc if str_lst.find(fi) > 0 else "not found in " +fc

Output Valuesは、私が検索したフィールドとその他のフィールドを持つフィーチャクラスの完全なリストが含まれていますnot found

値の出力を収集する

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.