数据清洗1:将地址信息进行规范整理

上周六,和好友吃了好吃的胖哥俩。是我第一次吃,还是带来了很多惊喜的。这家店可以排在我印象中深圳十大美食比较靠前的位置了,因为它是甜口的。
吃毕,我们去了星巴克,帮忙解决她最近遇到的一些代码问题。期间,她提出了一个实际要解决的问题,是将一个单元格的地址信息,转化为五列,分别含有邮编、省份、城市、区、街道地址部分的信息。当然还有批量处理文件的需求,所以最终用以下简单的代码帮她实现了她想要的功能。

import os
import re
import pandas as pd

dirdir = "c:\\users\\83439\\Documents\\Fighting for PhD\\project\\patent\\list"
os.chdir(dirdir)
file_path = dirdir
files = os.listdir(file_path)

for file in files:
    data = pd.read_csv(file)
    newdict = {"zipcode":[],"province":[],"city":[],"distinct":[],"street":[]}
    for i in range(0, data.shape[0]):
        line = data.loc[i, u"X.地址."]
        if line[0].isdigit():
            newdict["zipcode"].append(line[0:6])
            start = 6
            if line.find(u"省") + line.find(u"自治区") + 1 > 0:
                newdict["province"].append(line[start : ((line.find(u"省") > 0 and line.find(u"省") or line.find(u"自治区") + 2) + 1)])
                start = (line.find(u"省") > 0 and line.find(u"省") or line.find(u"自治区") + 2) + 1
            else:
                newdict["province"].append("")
            if line.find(u"市") > 0:
                newdict["city"].append(line[start: (line.find(u"市") + 1)])
                start = line.find(u"市") + 1
            else:
                newdict["city"].append("")
            if line.find(u"区") > 0 and line.find(u"园区") < 0 and line.find(u"工业区") < 0 :
                newdict["distinct"].append(line[start: (line.find(u"区") + 1)])
                start = line.find(u"区") + 1
            else:
                newdict["distinct"].append("")
            if start != len(line):
                newdict["street"].append(line[start: ])
            else:
                newdict["street"].append("")
        else:
            newdict["zipcode"].append("")
            start = 0
            if line.find(u"省") + line.find(u"自治区") + 1 > 0:
                newdict["province"].append(
                    line[start: ((line.find(u"省") > 0 and line.find(u"省") or line.find(u"自治区") + 2) + 1)])
                start = (line.find(u"省") > 0 and line.find(u"省") or line.find(u"自治区") + 2) + 1
            else:
                newdict["province"].append("")
            if line.find(u"市") > 0:
                newdict["city"].append(line[start: (line.find(u"市") + 1)])
                start = line.find(u"市") + 1
            else:
                newdict["city"].append("")
            if line.find(u"区") > 0 and line.find(u"园区") < 0 and line.find(u"工业区") < 0 :
                newdict["distinct"].append(line[start: (line.find(u"区") + 1)])
                start = line.find(u"区") + 1
            else:
                newdict["distinct"].append("")
            if start != len(line):
                newdict["street"].append(line[start:])
            else:
                newdict["street"].append("")
    data[u'邮编'] = pd.Series(newdict['zipcode'], index=data.index)  # 添加邮编
    data[u'省'] = pd.Series(newdict['province'], index=data.index)  # 添加省
    data[u'市'] = pd.Series(newdict['city'], index=data.index)  # 添加市
    data[u'区'] = pd.Series(newdict['distinct'], index=data.index)  # 添加区
    data[u'街道地址'] = pd.Series(newdict['street'], index=data.index)  # 添加街道地址
    tmp = file.split(".")
    data.to_csv(dirdir + "_result\\" + tmp[0] + "_address." + tmp[1] , encoding='ansi')  # 写入文件

当时的实现思路

从左到右遍历
第一步:判断字符串的第一个字符是不是数字,如果是,就包含了邮编信息,截取出前6位字符串;否则不做任何操作。
第二步:根据省市区的信息对剩余字符串进行切分,最终得到想要的信息。

在处理的时候,会出现某些信息缺失的情况,所以引入了一个游标来确定每个信息的起始位置,这样就可以较好地将所需要的信息提取完整。由于当时时间比较紧,只是利用代码实现了相应的功能,相对来说比较粗糙,所以回来以后就在思考:如何可以更加优雅地实现这个功能,让实现逻辑更简单,代码量更小呢?

更加具体的问题描述

首先,我们处理的是中文地址的数据清洗问题。由于中文地址的书写习惯是正序的,相对来说,这种天然设定相应的降低了问题的难度。接下来,总结一下,在处理的时候会遇到哪些问题:

  • 某些信息存在缺省,比如深圳市XXX,就是缺省了“广东省”的信息
  • 省和自治区是一个同级层次,所以需要进行特殊的处理
  • 区这个层级的会与其他信息混淆,如“开发区”、“高新区”等。

输入输出demo列举

  • 输入:福建省厦门市思明区望海路6号 输出:福建省,厦门市,思明区,望海路6号
  • 输入:厦门市思明区望海路6号 输出:,厦门市,思明区,望海路6号
  • 输入:福建省思明区望海路6号 输出:福建省,,思明区,望海路6号

第一次尝试:

未完待续。。。

comments powered by Disqus