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

创作背景

本菜鸡最近在数据分析时遇到这样一列数据,如图
在这里插入图片描述
我想进行的操作是:

  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 的小伙伴可以 私信我 进群哦。

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

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值