對於在運行過程中只用到一次,但是會嚴重影響運行效率的數據,在使用過后立刻刪除,以提高運行效率。
遙感影像信息提取中,有預判、審核兩步。對於同一塊地區,預判作業員先勾畫出目標地物並賦值,完成之后復制一份矢量交給審核作業員檢查,審核作業員在預判的基礎上修改圖斑形狀、屬性,或者刪除、添加圖斑。
現在需要對比兩份矢量,計算預判作業員的錯誤率、遺漏率,主體代碼很簡單,就是遍歷審核后的矢量(審核矢量),找出每個圖斑對應的預判矢量圖斑,比較。如果找不到對應的圖斑,則認為是遺漏。
shapeChange = attrChange = missing = 0; ISpatialFilter preFilter = new SpatialFilterClass(); preFilter.SpatialRel = esriSpatialRelEnum.esriSpatialRelWithin; IFeature chkFeat = null; IFeatureCursor chkCur = chkClass.Search(null, false); while ((chkFeat = chkCur.NextFeature()) != null) { IArea chkArea = chkFeat.Shape as IArea; preFilter.Geometry = chkArea.LabelPoint; IFeatureCursor preCur = preClass.Search(preFilter, false); IFeature preFeat = preCur.NextFeature(); if (preFeat == null) { missing++; continue; } IRelationalOperator relOp = chkFeat.Shape as IRelationalOperator; object preAttr = preFeat.get_Value(preIndex); object chkAttr = chkFeat.get_Value(chkIndex); //開始圖形比較 if (!relOp.Equals(preFeat.Shape)) { shapeChange++; continue; } if (!preAttr.Equals(chkAttr)) { attrChange++; continue; } }
這段代碼在圖斑數量不上萬的情況下運行良好,然而圖斑數量變多之后效率急速下降,兩份5萬左右的矢量,一夜都沒比較完。經過排查,時間開銷最大的是空間查找對應圖斑這段代碼。因此我試着在圖形比較之前添加以下代碼,刪除與審核圖斑屬性形狀都相同的預判圖斑。
if (relOp.Equals(preFeat.Shape) && preAttr.Equals(chkAttr)) { preFeat.Delete(); continue; }
結果原先一夜跑不完的數據只用了半小時就搞定。
這里就是我想要說的思路,對於在運行過程中只用到一次,但是會嚴重影響運行效率的數據,在使用過后立刻刪除,以提高運行效率。
想到這個思路后兩天,又遇到了一個數據量很大的需求。有一份矢量,要求其中一個字段里的值不能有重復,但是檢查之后發現有1萬多圖斑的值有重復,需要找出這1萬多圖斑。我的實現代碼如下:
# coding:utf-8 import os import arcpy orishp=arcpy.GetParameterAsText(0) uniquefd==arcpy.GetParameterAsText(1) scur=arcpy.da.SearchCursor(orishp,[uniquefd]) allvalues=[row[0] for row in scur] dcur=arcpy.da.UpdateCursor(orishp,[uniquefd]) for row in dcur: if allvalues.count(row[0])==1: allvalues.remove(row[0]) dcur.deleteRow()
倒數第二行,我把數組里只出現一次的值都刪除,使執行allvalues.count()所需的時間逐次減少,以提高效率。
用一份40萬個圖斑的矢量測試,以上代碼需要16分鍾,把倒數第二行注釋之后再測試,需要30分鍾,消耗的時間增加了幾乎一倍。
最近遇到的業務量越來越大,如果有其他好的提高效率的方法,希望大家多指點。