Python 목록에있는 경우 속성별로 기능을 선택 하시겠습니까?


14

파이썬에서 속성 별 선택을 완료하려고하지만 속성이 목록에 있는지 여부에 대한 쿼리를 기반으로합니다.

가장 간단한 쿼리는 다음과 같아야합니다.

qry = " \"OBJECTID\" in oid_list"
arcpy.SelectLayersByAttribute_management(inft, "NEW_SELECTION", qry)

그러나이 방법은 잘못된 식 오류를 반환합니다.

과거에는 이러한 유형의 쿼리에 대해 더 복잡한 구문을 사용해야했습니다.

sqlQuery2 = "nid in (" + ','.join(["'"+x+"'" for x in delta_list]) +")"

그러나이 스 니펫의 적응은 나에게도 효과가없는 것 같습니다.

 "OBJECTID_1 in (" + ','.join(["'"+str(x)+"'" for x in oid_list]) +")"

내가 여기서 무엇을 놓치고 있습니까?

답변:


16

원래 쿼리는 정수 목록으로 수정되었을 수 있습니다.

'"OBJECTID_1" IN ' + str(tuple(oid_list))

따라서 인 경우 oid_list = [7, 9, 4, 8]결과는 다음과 같습니다.

"OBJECTID_1" IN (7, 9, 4, 8)

경우에이 작품을 "속임수"고주의 oid_list항상 두 개 이상의 항목이 같은 다른 유효한 튜플, 이후, ()또는 (7,)하는 SQL 구문 오류가 발생합니다.

0 개 또는 하나의 oid_list항목을 처리하는보다 일반적인 표현식 은 다음과 같습니다.

'"OBJECTID_1" IN ({0})'.format(', '.join(map(str, oid_list)) or 'NULL')

ArcGIS 선택 인터페이스가 'IN'을 지원한다는 것을 알지 못했습니다. 이것은 아마도 내 솔루션보다 더 효율적입니다.
AHigh

1
IN 쿼리에 의해 지원되는 상한선이 있다는 것을주의하십시오. 2000 개 레코드라고 생각합니다
Tristan Forward

9

다음은 세미콜론으로 구분 된 문자열 대신 Python 목록을 허용하기 위해이 답변 에서 약간 수정 된 함수 버전입니다 .

def buildWhereClauseFromList(table, field, valueList):
    """Takes a list of values and constructs a SQL WHERE
    clause to select those values within a given field and table."""

    # Add DBMS-specific field delimiters
    fieldDelimited = arcpy.AddFieldDelimiters(arcpy.Describe(table).path, field)

    # Determine field type
    fieldType = arcpy.ListFields(table, field)[0].type

    # Add single-quotes for string field values
    if str(fieldType) == 'String':
        valueList = ["'%s'" % value for value in valueList]

    # Format WHERE clause in the form of an IN statement
    whereClause = "%s IN(%s)" % (fieldDelimited, ', '.join(map(str, valueList)))
    return whereClause

6

가장 간단한 접근 방법은 목록의 값을 개별적으로 반복하여 선택 항목에 추가하는 것입니다 (목록의 각 값으로 쿼리를 변경할 수 있음). 이 같은:

oidList = [1,2,3,4]
arcpy.management.MakeFeatureLayer(thisFC,thisLyr)
for values in oidList:
    query = "\"OBJECTID\"="+str(values)
    arcpy.management.SelectLayerByAttribute(thisLyr,"ADD_TO_SELECTION",query)

선택된 기능이 없더라도 ADD_TO_SELECTION을 사용할 수 있으며 첫 번째 반복에서 새로운 선택을 생성합니다.

편집하다:

개별 SelectLayerByAttribute를 수행하는 데 드는 비용이 너무 높다고 생각하는 경우 목록 길이에 따라 상당히 큰 선택 절을 작성하는 다음과 같은 방법을 사용할 수 있습니다.

oidList = [1,2,3,4]
arcpy.management.MakeFeatureLayer(thisFC,thisLyr)
query=""
q=""
oidList.sort()
for x in oidList:
    query="\"OBJECTID\"="+str(x)+" OR "+q
    q=query
q=q[1:-4]
arcpy.management.SelectLayerByAttribute(thisLyr,"NEW_SELECTION",q)

값을 반복하고 각 반복마다 속성별로 선택을 수행하는 흥미로운 아이디어. 나는 이것을 테스트 할 것이지만 이것이 효과가 있다고 확신합니다. 감사.
jsnider

이것은 작동하는 것처럼 보이지만 더 긴 목록을 위해 각 개별 선택을 처리하는 데 시간이 걸릴 것입니다.
jsnider

2
다른 접근 방식으로 답변을 업데이트했습니다.
AHigh

업데이트 된 답변으로 좋은 생각입니다. 더 큰 목록을 처리하는 데 훨씬 빠른 속도로이 방법을 사용하기로했습니다. oid_set의 x에 대해 q = "": q = "": query = ' "OBJECTID_1"='+ str (x) + 'OR'q = query q = q [1 : -4] 다음 속성별로 선택하십시오. 작동하는 것 같습니다!
jsnider

선택한 접근 방식으로 내 대답을 업데이트하여 구문 분석되고 쉽게 읽을 수 있습니다. 다행이다.
AHigh
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.