正则 两个相同的汉字_【python与债券】Step3:中介成交数据整理by正则表达式

正则表达式是字符串处理必备的科目,也是结构化数据变成结构化数据的一个关键环节,还有就是爬虫中非常重要的一步,所以先从一个简单的大家感兴趣的日常工作的切口,入门一下正则表达式。

有交易员朋友提出想整理一下成交数据,很多交易员收盘会获得一些中介粘贴的表,但是不同的中介给的格式有所微妙的差异,所以需要手动整理一下,如果能有每一天保存下来的数据,就可以回溯成交啦。

候要感谢现券汪和其中不辞辛苦传数据一位群友,一位交易员提供的需求哈~

我们首先要看一下数据格式是什么样的:

284ae37dae8b5d7eb22d4989bc59804f.png

64d51e9225a080d7a90c7621c12a0546.png

惯例声明,这次不用声明wind的接口了。utf-8是一定的,如果大家比较费解,可以百度utf-8gbk

# -*- coding: utf-8 -*-import pandas as pdimport reimport numpy as np

读取群里面发的一天的中介的文件。file_obj是读取文件的一个指针,后面的.readlines()是调用分行读取的方法,然后要关闭文件指针.close()

file_obj = open('2019年09月02日周一.txt')lines = file_obj.readlines()file_obj.close()

正则表达式书写:分别是期限、债券简称、债券代码、评级、成交价格的正则表达式。我分别解释一下正则表达式的逻辑,关于正则表达式的具体含义可以搜索Python 正则表达式 | 菜鸟教程和在线正则表达式测试

pet_term = '[\.\d]+[YMD]'pat_name = '[\d\w]+[\u4e00-\u9fa5]+[\d\w]+'pet_code = '\d{6}[A-Z0-9]*'pat_rating = '[A]*AA[+-]*'pet_price = '\d+\.\d+'pet_xingquan = '\u884c\u6743'

1. 期限:[\.\d]是匹配任意包含有"."和各类数字的字符,+意思是前面方括号中的变量可以任意重复多次(但是至少要出现一次),[YMD]意思是只要包含方括号中Y,M,D中任意一个就可以,因为期限数据必然含有这三个字母加上数字的组合。

2. 简称:三个部分,[\d\w]是意味着数字,[\u4e00-\u9fa5]意味着是任意汉字,这个就是汉字在unicode编码中的数位,所以我构成了 数字+汉字+英文与数字的这种债券简称结构,比如17中铝MTN002

3. 代码:代码基本上就是六位以上的纯数字或者加上.sh,.ib,.sz等,利率债是六位,190210,信用债多一些,比如011901659,所以正则表达式的含义就是在至少满足六位数字的前提下,后面会有任意位数的字母或者数字,其实[0~9]的含义等于[\d].

4. 评级:评级至少会有AA,所以在前面加一个可选的[A],*意味着可以有任意一个前面的字符,包括0,但是+至少是1。后面是可选的+或者是-,意味着某些债既可以是AA-也开始是AA+

5. 价格:有小数点的小数就可以,比如成交价格3.45,不过这部分会和第一部分的1.68Y相冲突,我还没想好正则表达式改怎么剔除,所以选择在程序里面进行剔除。

6.是否行权:直接与这两个字符进行匹配,'\u884c\u6743',这两个字符分别代表“行”和“权”两个数字的编码,具体某个汉字的unicode是什么可以参考搜索:Unicode编码转换 - 站长工具

生成一个空的dict字典进行数据的保存。

data_series ={'剩余期限':[],              '简称':[],              '代码':[],              '评级':[],              '成交价':[],              '是否行权':[]}

开始对每一行进行循环和字符串匹配,结果存入data_series

# 对lines的每一行进行循环for line in lines:        line_spt = line.split()    # 如果对某一行line的根据空格切分后,单位少于3个,就不进行运算,进行下一步循环    if len(line_spt) < 3:        continue        # 利用正则表达式的条件,筛选出满足正则表达式条件的数据    idata = re.findall(pet_term, line)    # 如果没有匹配到,则返回的是空list,这样将NaN赋值给相应的位置    if len(idata) == 0:        data_series['剩余期限'].append(np.nan)    else:        data_series['剩余期限'].append(idata[0])    idata = re.findall(pat_name, line)    if len(idata) == 0:        data_series['简称'].append(np.nan)    else:        data_series['简称'].append(idata[0])    idata = re.findall(pet_code, line)    if len(idata) == 0:        data_series['代码'].append(np.nan)    else:        data_series['代码'].append(idata[0])    idata = re.findall(pat_rating, line)    if len(idata) == 0:        data_series['评级'].append(np.nan)    else:        data_series['评级'].append(idata[0])        # 如果匹配的数据多余1个,则选择结果的后面一个作为成交    idata = re.findall(pet_price, line)    if len(idata) == 0:        data_series['成交价'].append(np.nan)    elif len(idata) == 1:        data_series['成交价'].append(idata[0])    else:        data_series['成交价'].append(idata[1])        idata = re.findall(pet_xingquan, line)    if len(idata) == 0:        data_series['是否行权'].append(np.nan)    else:        data_series['是否行权'].append(idata[0])

将list数据转换成dataframe,然后输出成csv格式。

data_pd = pd.DataFrame(data_series)data_pd.to_csv('output.csv', encoding="utf_8_sig")

dataframe的view:

3a42e065514e08f2a4a802790b351996.png

csv:

9620fe75b89710f9c9cace38cdbc04a4.png

关于原始数据、代码、清洗后的数据,保存到了网盘上:

链接: https://pan.baidu.com/s/12TeeKEomElYMtH8cj8UCVQ 

提取码: bykw

如果整理一个文件夹所有的,在读取的时候遍历一个文件夹内所有的文件,要import os啊

如有需求请跟我讲哈,多谢关注和支持~

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值