以前记录过相关文章《Python实现矢量数据的自然断点分级》,成果是一个Arcmap工具,自己使用时挺方便,但有一个缺点是需要安装第三方的自然断点分级库,换一台电脑又要配置一下环境。如果只是偶尔临时使用一下这个工具,配置过程显得很呆,特别是离线环境下,对任何文件数据拷贝都很严格的时候。
于是重新完善了相关代码,在Arcmap中可以直接使用,无需安装额外的库。
import arcpydef GetScore(break_num, score_flag): """根据分类编号返回对应分数""" if score_flag: # 分数列表,索引 0~8 对应 1~9 类 scores = [0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9] # 安全判断,防止越界 if 1 <= break_num <= len(scores): return scores[break_num - 1] return break_num# ===================== 【配置项】 =====================In_Layername = "测试数据"In_Originalfield = "X1平均高程"out_Classfield = "X1Re_Class"out_Rangefield = "X1Re_Range"score_Flag = False# ======================================================mxd = arcpy.mapping.MapDocument("CURRENT")df = arcpy.mapping.ListDataFrames(mxd)[0]lyr = arcpy.mapping.ListLayers(mxd, In_Layername, df)[0]# 检查是否分级符号if lyr.symbologyType in ("GRADUATED_COLORS", "GRADUATED_SYMBOLS"): graduated = lyr.symbology break_vals = graduated.classBreakValues break_labels = graduated.classBreakLabels break_nums = graduated.numClasses print("break_vals :", break_vals) print("break_labels :", break_labels) print("break_nums :", break_nums) # ========== 创建字段(文本长度40) ========== if not arcpy.ListFields(lyr, out_Classfield): arcpy.AddField_management(lyr, out_Classfield, "DOUBLE") if not arcpy.ListFields(lyr, out_Rangefield): arcpy.AddField_management(lyr, out_Rangefield, "TEXT", field_length=50) # ========== 核心:遍历赋值(修复逻辑错误) ========== with arcpy.da.UpdateCursor(lyr, [In_Originalfield, out_Classfield, out_Rangefield]) as cursor: for row in cursor: val = row[0] # 空值直接跳过 if val is None: row[1] = None row[2] = "空值" cursor.updateRow(row) continue # 遍历区间判断(正确写法) found = False for i in range(break_nums): lower = break_vals[i] upper = break_vals[i+1] if i == 0: # 第一类:包含下限 if lower <= val <= upper: row[1] = GetScore(i+1, score_Flag) row[2] = break_labels[i] found = True break else: # 其他类:左开右闭 if lower < val <= upper: row[1] = GetScore(i+1, score_Flag) row[2] = break_labels[i] found = True break # 异常值处理 if not found: row[1] = -99 row[2] = "超出范围" cursor.updateRow(row) print("✅ 重分类完成!")else: print("❌ 图层未设置分级色彩/分级符号,请检查!")del mxd
虽然Arcgis中的Arcpy没有直接对矢量数据的属性进行自然断点重分类的函数,但可以间接获取到自然断点值。在Arcgis符号系统中可以对图层进行符号化以表示数量,在使用分级色彩与使用分级符号类中,可以选择自然断点的分类方法,而我们可以利用python读取这个分类后的值。
具体使用过程如下:
测试数据
在python窗口中粘贴代码,根据实际情况修改数据图层名称,原始字段名称,输出字段名称,以及设置直接赋值1、2、3…的等级还是赋值0.1、0.2、0.3…的评分。