用python处理arcgis导出的地类excel表

算是杂记,经常在微信里看到9块9学python处理excel,一直没机会。正好最近有个本科室友找我,问能不能给他处理个工程测算表,指明了要用python来做。本科的铁哥们,这忙咱得帮。说干就干,首先当然是不去报班买9块9的课程。

首先,看看要处理的表是啥样,他想要的处理结果是啥样

老铁做测量多年,用excel表滑溜的很,他是为了报单位的创新项目,所以才想用python提高一下科技含量。他对自己要处理的表和处理成啥样了然于心。
原表是一张arcgis导出的各地类的测量面积表,里面有上千个图斑,也就对应着上千条记录。要处理成一张汇总表,根据项目、镇界统计各地类的面积。看着不算难,但是各类统计以及按格式填表,着实让我忙活了一阵。

以下为原始数据表:

arcgis导出表.png

统计汇总表:

成果汇总表.png

可以从汇总表中看到,统计分两个维度,一个是根据项目及镇、村来统计各地类的总面积,还有一个维度是统计该区域内各地类的总面积。

高效统计法推荐

这里不得不提到一个python库——pandas,能够像操作数据库那样进行分组操作。

data_arcgis = pd.read_excel(inputfile, inputsheetname)
grp1 = data_arcgis.groupby(['权属', '镇界', '界线', 'DLMC', '地类', '分区']).agg({'亩': ['sum']}).reset_index()

通过权属、镇界、地类等对原始数据进行最小粒度的分组,这样操作就能获得最小粒度数据,为后面的汇总打下数据基础

grp3 = grp2.groupby(['镇界'])
Town_list = list(grp3.groups.keys())  ###获取镇界枚举值

通过该方法获得组内的枚举值,为写入汇总表里的镇、村准备数据源

    for town in Town_list:
        grp4 = grp2[grp2['镇界'] == town]
        grp5 = grp4.groupby(['分区'])
        Fq_list = list(grp5.groups.keys())   ###获取分区枚举值
        town_total = grp4.agg({'亩': ['sum']}).reset_index()['亩'].iloc[0,0]
        #print(town + ':' + str(town_total))
        sheet.cell(row = startrowindex + lineindex, column=4).value = town
        sheet.cell(row = startrowindex + lineindex, column=4).font = font
        sheet.cell(row = startrowindex + lineindex, column=8).value = town_total
        sheet.cell(row = startrowindex + lineindex, column=8).font = font
        lineindex = lineindex + 1
        for fq in Fq_list:
            grp6 = grp4[grp4['分区'] == fq]
            grp7 = grp6.groupby(['界线'])
            Jx_list = list(grp7.groups.keys())   ###获取界线枚举值
            for jx in Jx_list:
                grp8 = grp6[grp6['界线'] == jx]
                grp9 = grp8.groupby(['地类'])
                Dl_list = list(grp9.groups.keys())   ###获取地类枚举值
                jx_total = grp6[grp6['界线'] == jx].agg({'亩': ['sum']}).reset_index()['亩'].iloc[0,0]
                #print('    ' + fq + ':' + jx + ':' + str(jx_total)) 
                sheet.cell(row = startrowindex + lineindex, column=2).value = fq
                sheet.cell(row = startrowindex + lineindex, column=2).font = font
                sheet.cell(row = startrowindex + lineindex, column=5).value = jx
                sheet.cell(row = startrowindex + lineindex, column=5).font = font
                sheet.cell(row = startrowindex + lineindex, column=8).value = jx_total
                sheet.cell(row = startrowindex + lineindex, column=8).font = font
                for dl in Dl_list:
                    dl_total = grp8[grp8['地类'] == dl].agg({'亩': ['sum']}).reset_index()['亩'].iloc[0,0]
                    dic_dl_value[dl] = dic_dl_value[dl]  + dl_total
                    total_sum = total_sum + dl_total
                    sheet.cell(row = startrowindex + lineindex, column=dic_dl_column[dl]).value = dl_total
                    sheet.cell(row = startrowindex + lineindex, column=dic_dl_column[dl]).font = font
                    #print('        ' + dl + ':' + str(dl_total)) 
                lineindex = lineindex + 1

依次遍历镇界、分区、界线、地类,最后在地类循环中,对相同地类进行累计求和。至此就可以获得相应镇界、分区、界线下的地类汇总面积,同时通过lineindex来计算写入的行号,保证了运算结果写入到争取的行列内。

令人头疼的难点

方法不难,最头疼的还是原始数据的不规范带来的不必要的程序消耗。因为原始数据中地类写入的随意性,以及新增临时地类(即不在汇总表内的地类),则需要进行额外的处理。
处理原则是,只要原始数据中地类名称有和汇总表内的字段名相匹配的,则认为命中,记录下该字段在excel中的列号,如果不在,则放入汇总表内的最后列。程序跑完后,由人工介入处理。

def setDlcolumn(all_dl_list, dl_type_series, dic_dl_column):
    dl_column_length = dl_type_series.shape[0]
    dl_column_length_bak = dl_column_length
    for dl_target in all_dl_list:
        colum_index = 0
        flag = 0
        for dl_type in dl_type_series.array:
            colum_index = colum_index + 1
            if str(dl_type) == 'nan':
                continue
            if dl_target in dic_dl_column and dic_dl_column[dl_target] < dl_column_length_bak: ###字典里已存在该地类
                flag = 1
                break
            if dl_target in dl_type:   ###如果arcgis中地类包含在样表中,则记录下列号
                flag = 1
                dic_dl_column[dl_target] = colum_index
                break
        if flag == 0:
            dl_column_length = dl_column_length + 1
            dic_dl_column[dl_target] = dl_column_length
    return dic_dl_column

处理效果

程序输出结果表.png

最后输出的结果,数值和统计结果一致,样式上还有所欠缺,需要利用openpyxl对表格进行样式修饰。基本达到老铁预期。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,590评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 86,808评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,151评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,779评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,773评论 5 367
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,656评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,022评论 3 398
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,678评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 41,038评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,659评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,756评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,411评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,005评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,973评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,203评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,053评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,495评论 2 343