栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Python

Python 重写一个提取字符串中行政区划的 Series(上)

Python 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Python 重写一个提取字符串中行政区划的 Series(上)

Python 重写一个提取字符串中行政区划的 Series(上)
    • 创作背景
    • 思路分析 - 提取行政区划
      • eg1:福建省莆田市城厢区
      • eg2:新疆维吾尔自治区乌鲁木齐市
      • eg3:青海省共和县
      • 泛化
    • 结尾

创作背景

本菜鸡最近在数据分析时遇到这样一列数据,如图

我想进行的操作是:

  1. 提取其中 各行政区划及名称。eg: 江苏省,北京市 这种。详见本文。
  2. 像 pd.to_datetime() 后可以调用 time_series.dt.year 返回对应的 年序列 一样,我的 area_series 可以返回对应的 省,市,市辖区/县。详见文章。
  3. 注:本文将 市辖区 和 县 认为是 平级,便于数据提取,如有不妥请指正。

如果觉得我这篇文章写的好的话,能不能给我 点个赞 ,评论 一波。
如果要点个 关注 的话也不是不可以珞

思路分析 - 提取行政区划

首先,我们得提取字符串中的 行政区划,怎么提取呢?当然是用 re 了!
分析一下字符串(以 福建省莆田市城厢区 、 新疆维吾尔自治区乌鲁木齐市 和 青海省共和县 为例)。

eg1:福建省莆田市城厢区

这个好分析

  • 省级行政区 是 福建省。
  • 市级行政区 是 莆田市。
  • 市辖区 是 城厢区。

那我们就可以这样写正则表达式

(S+省)(S+市)(S+区)

测试一下

可以看到,都提取出来了,但是,我们要的数据在一个 list 里的一个 tuple 元素中,不利于后期处理,所以我们修改一下。

修改后的正则表达式:

S+省|S+市|S+区

再看一下效果:

这时候我们要的数据就在一个 list 里了。

eg2:新疆维吾尔自治区乌鲁木齐市

这个字符串中:

  1. 省级行政区 是 新疆维吾尔自治区。
  2. 市级行政区 是 乌鲁木齐市。
  3. 没有 县级行政区。

仿照上边的,我们可以这样写正则表达式:

S+自治区|S+市

看一下结果:

eg3:青海省共和县

我们可以看出:

  1. 省级行政区 是 青海省。
  2. 没有 市级行政区。
  3. 县级行政区 是 共和县。
  4. 注:目测是 县级行政区,此处 仅供举例说明,如有更改请指出。

那我们就这样写正则表达式:

S+省|S+县

看一下结果:

泛化

从上述三个例子可以看出,我们可以使用 S+【行政区划】 即可提取到对应的 行政区划及其名称 。

但是有个问题,上述三个正则表达式 泛化能力不强,要不然怎么需要 三 个正则表达式而不是 一个 才能提取到我们想要的结果。
那我们现在就要写一个 泛化能力强 的正则表达式,能够匹配这个地点序列中所有的字符串。

分析可得,地名都是由 【省级行政区】【市级行政区】【市辖区 / 县级行政区】 组成。
其中:

  1. 省级行政区 包括 省,自治区。
  2. 市级行政区 包括 市,旗。
  3. 市辖区 / 县级行政区 包括 区,县。

我们可以这样写:

S+省|S+自治区|S+市|S+旗|S+区|S+县

可是这又带来两个问题:

  1. 各级行政区后缀名 名称不止我列举的这些,还可能有其他的,要新增到正则表达式的话有些麻烦。
  2. 提取出来的结果无法分辨出相应的行政区划。

怎么解决呢?
我的思路是:

  1. 创建一个 行政区划列表,固定包含 三 个元素。
  2. 每个元素是 list,包含 该等级行政区划的后缀名。
  3. 拼接正则表达式。

代码如下

divisions = {
    'province': ['省', '自治区'], 
    'city': ['市'], 
    'county': ['区', '县', '旗']
}

# 正则表达式 'S+省|S+自治区|S+市|S+旗|S+区|S+县'
re.findall('|'.join(['|'.join(['S+' + char for char in chars]) for chars in divisions.values()]), '【要提取的字符串】')

测试一下:

  • 福建省莆田市城厢区
  • 新疆维吾尔自治区乌鲁木齐市
  • 青海省共和县

看起来效果还不错,相对来说还是有 一定的泛化能力。

为了方便后边的数据处理,我们规定一下输出格式:

['【省】', '【市】', '【市辖区 / 县】']

代码如下:

def check_exist(area, names):
    for name in names:
        if name in area:
            return area
    else:
        return ''

divisions = {
    'province': ['省', '自治区'], 
    'city': ['市'], 
    'county': ['区', '县', '旗']
}
# 提取结果列表
result = re.findall('|'.join(['|'.join(['S+' + char for char in chars]) for chars in divisions.values()]), '【要提取的字符串】')

# 手动设置索引
count = 0
# 结果列表
result_list = []

# 遍历行政区划列表,保证结果列表长度与其相等
for key in divisions:
    # 如果索引小于提取结果长度
    if count != len(result):
        # 查看是否属于 key 这个行政区划
        test_exist = check_exist(result[count], divisions[key])
        # 如果属于本行政区划,加入结果列表
        result_list.append(test_exist)
        if test_exist:
            count += 1
    else:
        # 提取结果遍历完但行政区划列表还未遍历完,说明后边的行政区划都没有,就加入空字符
        result_list.append('')
        
print(result_list)

测试一下:

成功完成任务!!!




结尾

有想要一起学习 python 的小伙伴可以 私信我 进群哦。

以上就是我要分享的内容,因为学识尚浅,会有不足,还请各位大佬指正。
有什么问题也可在评论区留言。

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/357109.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号