Chọn tính năng theo thuộc tính nếu trong danh sách Python?


13

Tôi đang cố gắng hoàn thành một lựa chọn theo thuộc tính trong Python nhưng dựa trên truy vấn xem một thuộc tính có trong danh sách hay không.

Một truy vấn đơn giản nhất phải giống như thế này:

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

nhưng cách tiếp cận đó trả về một lỗi biểu thức không hợp lệ.

Trước đây, tôi đã phải sử dụng sytax phức tạp hơn cho loại truy vấn này, chẳng hạn như:

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

nhưng một bản chuyển thể của đoạn trích này dường như cũng không hiệu quả với tôi, ví dụ:

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

Tôi đang thiếu gì ở đây?

Câu trả lời:


15

Truy vấn ban đầu của bạn có thể đã được sửa đổi cho một danh sách các số nguyên:

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

vì vậy nếu oid_list = [7, 9, 4, 8], thì kết quả là:

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

Hãy nhận biết rằng đây "đánh lừa" các công trình nếu oid_listluôn luôn có hai hoặc nhiều mặt hàng, từ các bộ giá trị khác, chẳng hạn như ()hay (7,), sẽ cho kết quả có lỗi cú pháp SQL.

Một biểu thức chung hơn cũng sẽ xử lý 0 hoặc một oid_listmục sẽ là:

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

Tôi không nhận ra giao diện lựa chọn ArcGIS được hỗ trợ 'IN'. Điều này có lẽ hiệu quả hơn giải pháp của tôi.
AHigh

1
Hãy cảnh giác, có một giới hạn trên được hỗ trợ bởi truy vấn IN Tôi nghĩ đó là 2000 bản ghi
Tristan Forward

9

Đây là một phiên bản sửa đổi một chút của hàm trong câu trả lời này , để chấp nhận danh sách Python thay vì chuỗi được phân cách bằng dấu chấm phẩy:

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

Tôi nghĩ rằng cách tiếp cận đơn giản nhất cho việc này là lặp qua các giá trị trong danh sách của bạn và thêm chúng vào vùng chọn (Vì vậy, bạn có thể thay đổi truy vấn của mình với từng giá trị trong danh sách). Một cái gì đó như thế này:

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)

Bạn có thể sử dụng ADD_TO_SELMENT ngay cả khi không có tính năng nào được chọn, nó sẽ tạo ra một lựa chọn mới trong lần lặp đầu tiên.

Biên tập:

Nếu bạn nghĩ rằng chi phí để thực hiện ChọnLayerByAttribution riêng lẻ sẽ quá cao, bạn có thể sử dụng một cách tiếp cận như thế này khi bạn tạo một mệnh đề lựa chọn khá lớn tùy thuộc vào độ dài danh sách của bạn:

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)

Ý tưởng thú vị để lặp qua các giá trị và thực hiện chọn theo thuộc tính cho mỗi lần lặp. Tôi sẽ kiểm tra cái này, nhưng tôi khá chắc chắn cái này sẽ hoạt động. Cảm ơn.
jsnider

điều này dường như đang hoạt động, nhưng chắc chắn sẽ có thời gian để xử lý từng lựa chọn riêng lẻ cho danh sách dài hơn.
jsnider

2
Cập nhật câu trả lời với một cách tiếp cận khác.
AHigh

Ý tưởng tốt với câu trả lời cập nhật. Tôi đã chọn sử dụng phương pháp này vì nó nhanh hơn nhiều để xử lý các danh sách lớn hơn. Được sửa đổi một chút Có vẻ để làm việc!
jsnider

Tôi sẽ cập nhật câu trả lời của tôi với cách tiếp cận đã chọn của bạn để nó được phân tích cú pháp và dễ đọc hơn. Vui mừng nó đã làm việc.
AHigh
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.