如何將Excel表批量賦值到ArcGIS屬性表

情景再現

現須要將Excel表信息批量賦值(不是掛接)到Shp文件的屬性表,兩張表的字段、記錄數如出一轍,至於爲何會出現這樣的問題,咱也不敢問,只有想個法子把它搞定!python

原始的Excel信息表共57列,總共3萬多條記錄,包含了正確的記錄數據,以下:編程

目標的ArcGIS屬性表也是57列(不是Table表,是要素類的屬性表),記錄中的信息不正確,以下:app

好在它們的FID字段能夠一一對應,如今須要根據Excel屬性表把ArcGIS屬性表填充正確。工具

常規思路

最容易想到的方法是,用屬性錶鏈接Excel表,而後利用字段計算器,分別進行計算。學習

因爲記錄有3萬多條,平均一個字段計算要8分鐘,這也得花一天時間啊,若是沒有其實方法,且不用管"白貓""黑貓",能解決就行。ui

編程思惟

從上面的方法,咱們會很快發現一個問題:50多個字段的計算都是重複一個步驟,在某個字段上右鍵,點擊"字段計算器"彈出窗口,選擇相應的字段,點擊肯定。這個過程簡單而無味,是否有讓電腦自動重複這個操做,解放咱們的雙手?答案是確定的,經過簡單的編程來實現重複的操做,對於本場景最佳編程方式是使用強大的Python腳本。對於新手來講也莫怕,編程並不可怕,可怕的是你遇到這種問題不會編程。下面來試一下:blog

簡單解釋一下:get

第一步,導入arcpy,這是ESRI給我造好的"輪子",引入它後能夠作全部地理處理的功能;input

第二步,直接調用字段計算的方法,方法名稱是:arcpy.CalculateField_management,其後面的括號帶四個參數,分別是計算的圖層名稱(即表名稱)、計算的字段(即在哪一個字段上右鍵調出字段計算器)、計算表達式(就是選擇的賦值字段)、Python版本(固定值);table

第三步,回車執行,糟糕,報錯了。沒關係,仔細分析一下,看是語法問題,仍是數據問題,重寫一句再執行就對了。

有了成功的開始,是否是增長信心。咱們不可能手動輸入50多句話,也很難寫的,得再想個法子來解放雙手(再次編程思惟)。強大的Excel上場了:用公式寫好一行,直接向下拖動(或雙擊右下角),呵呵,這個我最擅長了。

將這些正確語法的Python語句放在窗口中執行,連續兩次回車纔是執行哦!

接下來就慢慢等,雖然不須要反覆操做,但時間也要花好久。

收工。

---------回--------家---------吃---------飯--------

Too young to simple!第二行就報錯了

怎麼辦?有三種方案:

方案一:辭職轉行了,處理數據真是心累!

方案二:把問題返回給用戶,讓他們改好帶拿過來!(你覺得他們會聽你的嗎?你覺得他們能準備無誤地改得好嗎?)

方案三:百度、谷歌,查一下緣由,寫一個能容錯的腳本,學習一下ArcPy處理地理數據。

編程能力

接下來,纔是展現真正的技術的時候了。在鏈接好Excel表後,不使用字段計算器工具和腳本,並且是經過遍歷的方式賦值。

鏈接可保證行數相同。

鏈接後將數據導出後,將

下面這段代碼主要考慮三個問題:

(1)同名字賦值,如將Name_1的值賦給Name;

(2)缺失字段不賦值,若是不存在Name_1字段,則Name的值不重處理;

(3)忽略值與類型邏輯不一致的狀況,如Count字段的值不能爲空,默認爲0,而Count_1的值爲NULL.

代碼以下,不過多解釋,由於這不是本文重點。

import arcpy,os

input_table=arcpy.GetParameterAsText(0)

input_result=arcpy.GetCount_management(input_table)
input_count= int(input_result.getOutput(0))
arcpy.AddMessage("input count:"+ str(input_count))
oidFieldName=arcpy.Describe(input_table).OIDFieldName
allfields = arcpy.ListFields(input_table) 
lstFields=[]
for field in allfields:
    lstFields.append(field.name)
arcpy.AddMessage(lstFields)

# foreach all row and all field
cursor = arcpy.UpdateCursor(input_table)
for row in cursor:
    fields = arcpy.ListFields(input_table)
    oid=int(row.getValue(oidFieldName))
    if oid>1:
        arcpy.AddMessage(oid)   
    for field in fields:
        if field.required or field.name[-2:]=='_1':
            print('')
        else:
            targetField=field.name+'_1'
            if targetField in lstFields:
                newValue=row.getValue(targetField)
                try:
                    row.setValue(field.name,newValue)
                    #arcpy.AddMessage(field.name+":"+ str(newValue))
                except:
                    #arcpy.AddMessage(field.name+":except....")
                    pass
            else:
                print('')
                #arcpy.AddMessage(targetField+":is not exist")
    cursor.updateRow(row)

  

慢慢等結果了:

小結

一、要學會有編程(或程序)的思惟去解決問題,提升工做效率;

二、編程解決問題是一種能力,是慢慢學習積累的過程,沒有一本速成的書;

三、實際生產過程當中的數據每每不是理想的,有各類各樣的"陷阱"。

補充:

個別網友認爲我小題大做了,因爲原始數據不傳於上傳,因此我也再也不反駁:

相關文章
相關標籤/搜索