数据清洗及正则表达式入门
今日内容概要
-
数据清洗
-
数据操作小案例
-
前端之HTML标签
数据清洗
# 缺失值处理
cf.isnull().sum() # 快速统计每列缺失值数量
运行结果:
出发地 2
目的地 1
价格 28
节省 17
路线名 0
酒店 0
房间 0
去程航司 0
去程方式 0
去程时间 0
回程航司 0
回程方式 0
回程时间 0
dtype: int64
# 针对出发地的缺失值可能在路线里面有答案 所以需要自己查找并填充
cf[cf.出发地.isnull()]
运行结果:
出发地 目的地 价格 节省 路线名 酒店 房间 去程航司 去程方式 去程时间 回程航司 回程方式 回程时间
1850 NaN 烟台 647.0 348.0 大连-烟台3天2晚 | 入住烟台海阳黄金海岸大酒店 + 幸福航空/天津航空往返机票 烟台海阳黄金海岸大酒店 3.7分/5分 海景标准间(内宾)[双... 双床 双早 1间2晚 幸福航空 JR1582 直飞 10:05-11:05 天津航空 GS6402 直飞 16:30-17:25
1915 NaN 西安 1030.0 326.0 济南-西安3天2晚 | 入住西安丝路秦国际青年旅舍钟楼回民街店 + 华夏航空往返... 西安丝路秦国际青年旅舍钟楼回民街店 经济型 4.4分/5分 标准间(独卫)-吃货天... 双床 不含早 1间2晚 华夏航空 G54963 直飞 07:10-08:55 华夏航空 G58858 直飞
cf.loc[cf.出发地.isnull(),'出发地'] = [str(i)[:2] for i in cf.loc[cf.出发地.isnull(),'路线名']]
# 针对目的地的缺失值同样也可以在路线中找到答案
cf[cf.目的地.isnull()]
cf.loc[cf.目的地.isnull(),'目的地'] = str(cf.loc[cf.目的地.isnull(),'路线名'].values)[5:7]
# 价格的缺失值 用价格的均值填空 round后可以指定要保留的小数位数
cf['价格'].fillna(round(cf['价格'].mean(),0),inplace=True)
# 处理节省缺失值 用节省的均值填充
cf['节省'].fillna(round(cf['节省'].mean(),0),inplace=True)
# 验证
cf.isnull().sum()
# 处理文本型数据
正则表达式:通过一系列特殊符号在字符串中匹配出符合正则表达式的内容cf.head() # 观察每条路线的游玩时间(即几日几夜)、酒店评分
# 添加一列酒店评分数据
cf['酒店评分'] = cf.酒店.str.extract('(\d\.\d)分/5分',expand=False)
"""
expand=False 返回index/series expand=True 返回DataFrame
"""
# 添加酒店等级 cf['酒店等级'] = cf.酒店.str.extract('(.+)',expand=False)
cf['天数'] = cf.路线名.str.extract('(\d+)天\d晚',expand=False)
cf
运行结果:
出发地 目的地 价格 节省 路线名 酒店 房间 去程航司 去程方式 去程时间 回程航司 回程方式 回程时间 酒店评分 酒店等级 天数
0 哈尔滨 北海 2208.0 650.0 哈尔滨-北海3天2晚 | 入住北海祥丰嘉年华大酒店 + 春秋航空往返机票 北海祥丰嘉年华大酒店 舒适型 4.7分/5分 标准双人间(双床) 双床 不含早 1间2晚 春秋航空 9C8741 直飞 17:10-21:50 春秋航空 9C8742 直飞 10:20-15:05 4.7 北海祥丰嘉年华大酒店 舒适型 4.7分/5分 3
1 成都 泸沽湖 1145.0 376.0 成都-泸沽湖3天2晚 | 入住7天酒店丽江古城中心店 + 成都航空往返机票 7天酒店丽江古城中心店 经济型 4.0分/5分 经济房-不含早-限时特... 其他 不含早 1间2晚 成都航空 EU2237 直飞 19:45-21:20 成都航空 EU2738 直飞 23:30-01:05 4.0 7天酒店丽江古城中心店 经济型 4.0分/5分 3
2 广州 沈阳 2702.0 618.0 广州-沈阳3天2晚 | 入住沈阳中煤宾馆 + 南方航空/深圳航空往返机票 沈阳中煤宾馆 舒适型 4.5分/5分 大床间(内宾) 大床 双早 1间2晚 南方航空 CZ6384 直飞 08:05-11:45 深圳航空 ZH9652 经停 08:20-13:05 4.5 沈阳中煤宾馆 舒适型 4.5分/5分 3
3 上海 九寨沟 1954.0 484.0 上海-九寨沟3天2晚 | 入住红原芸谊大酒店 + 成都航空往返机票 红原芸谊大酒店 舒适型 4.6分/5分 豪华双床房[双早] 双床 双早 1间2晚 成都航空 EU6678 直飞 21:55-01:15 成都航空 EU6677 直飞 17:45-20:35 4.6 红原芸谊大酒店 舒适型 4.6分/5分 3
4 广州 天津 1608.0 422.0 广州-天津3天2晚 | 入住天津逸海明珠大酒店 + 奥凯航空/海南航空往返机票 天津逸海明珠大酒店 高档型 4.1分/5分 豪华双床房(预付) 双床 不含早 1间2晚 奥凯航空 BK2787 直飞 06:55-10:00 海南航空 HU7201 直飞 20:15-23:25 4.1 天津逸海明珠大酒店 高档型 4.1分/5分 3
... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ...
4995 大连 武汉 1473.0 368.0 大连-武汉3天2晚 | 入住武汉保利大酒店 + 南方航空/东方航空往返机票 武汉保利大酒店 豪华型 4.3分/5分 附楼标准间(双床) 双床 双早 1间2晚 南方航空 CZ8306 直飞 18:35-21:10 东方航空 MU2517 经停 07:40-12:05 4.3 武汉保利大酒店 豪华型 4.3分/5分 3
4996 成都 泸沽湖 1158.0 376.0 成都-泸沽湖3天2晚 | 入住丽江望月阁客栈 + 成都航空往返机票 丽江望月阁客栈 经济型 4.6分/5分 标准双人间-不含早(预... 双床 不含早 1间2晚 成都航空 EU2237 直飞 19:45-21:20 成都航空 EU2738 直飞 23:30-01:05 4.6 丽江望月阁客栈 经济型 4.6分/5分 3
4997 天津 丽江 1616.0 426.0 天津-丽江3天2晚 | 入住丽江凡间度假连锁客栈青旅店 + 天津航空/首都航空往... 丽江凡间度假连锁客栈青旅店 经济型 4.5分/5分 大床房-预付 大床 不含早 1间2晚 天津航空 GS7861 直飞 16:25-19:45 首都航空 JD5739 直飞 07:50-10:50 4.5 丽江凡间度假连锁客栈青旅店 经济型 4.5分/5分 3
4998 大连 重庆 1703.0 446.0 大连-重庆3天2晚 | 入住重庆酉阳锦宏大酒店 + 华夏航空/山东航空往返机票 重庆酉阳锦宏大酒店 舒适型 4.0分/5分 特惠房(大床) 大床 不含早 1间2晚 华夏航空 G52762 经停 18:25-23:30 山东航空 SC4837 经停 07:00-11:30 4.0 重庆酉阳锦宏大酒店 舒适型 4.0分/5分 3
4999 天津 哈尔滨 1192.0 356.0 天津-哈尔滨3天2晚 | 入住哈尔滨钰轩酒店中央大街店 + 奥凯航空/福州往返机票 哈尔滨钰轩酒店中央大街店 舒适型 4.0分/5分 标准大床房 大床 大床 双早 1间2晚 奥凯航空 BK2918 直飞 21:10-23:25 福州 FU6556 直飞 11:35-13:45 4.0 哈尔滨钰轩酒店中央大街店 舒适型 4.0分/5分 3
4996 rows × 16 columns
正则表达式
就是使用一对你暂时看不懂的符号去字符串中筛选出想要的结果
为什么要用正则表达式
能够更加简单快捷的完成数据的筛选、校验等一系列操作
while True:
phone_number = input('please input your phone number : ')
if len(phone_number) == 11 \
and phone_number.isdigit()\
and (phone_number.startswith('13') \
or phone_number.startswith('14') \
or phone_number.startswith('15') \
or phone_number.startswith('18')):
print('是合法的手机号码')
else:
print('不是合法的手机号码')
# 如果用正则一行代码就可以
phone_number = input('please input your phone number : ')
if re.match('^(13|14|15|18)[0-9]{9}$',phone_number):
print('是合法的手机号码')
else:
print('不是合法的手机号码')
# 要想在python中使用正则表达式需要借助于re模块(内置的不需要下载)
# 字符组的概念
re.findall('[a-z],res')
# 特殊符号(*******)
\d 匹配数字
\w 匹配字母数字下划线
^ 匹配字符串开头的字符(****************************)
^a
$ 匹配字符串结尾的字符(****************************)
b$
# 补充两者结合使用之后就可以明确的限制支持的开头和结尾即中间的字符
| 可以连接多个符号彼此之间是或的关系
() 给正则表达式分组(在findall方法中会有限展示括号内正则表达式匹配到内容)
[^] 如果在中括号的内部写^那么意思是除了后面跟的东西之外的所有字符
# 量词(个数)
量词不能单独使用 必须配合正则表达式符号
"""
在正则表达式中 默认都是贪婪匹配
尽可能的往多的方向匹配
"""
* 重复零次或多次
+ 重复一次或多次
? 重复零次或一次
{n} 重复n次
{n,} 重复n次或更多次
{n,m} 重复n到m次
具体案例
C:\Users\Administrator>ipython
Python 3.6.8 (tags/v3.6.8:3c6b436a57, Dec 23 2018, 23:31:17) [MSC v.1916 32 bit (Intel)]
Type 'copyright', 'credits' or 'license' for more information
IPython 7.16.1 -- An enhanced Interactive Python. Type '?' for help.
In [1]: import re
In [2]: re.findall('水.','水流水池水渠')
Out[2]: ['水流', '水池', '水渠']
In [3]: re.findall('^水','水流水池水渠')
Out[3]: ['水']
In [4]: re.findall('^水.','水流水池水渠')
Out[4]: ['水流']
In [5]: re.findall('水.$','水流水池水渠')
Out[5]: ['水渠']
# 量词的用法(贪婪匹配)
IIn [6]: re.findall('张.?','张英和张飞和张老三子')
Out[6]: ['张英', '张飞', '张老']
In [7]: re.findall('张.*','张英和张飞和张老三子')
Out[7]: ['张英和张飞和张老三子']
In [9]: re.findall('张.+','张英和张飞和张老三子')
Out[9]: ['张英和张飞和张老三子']
In [10]: re.findall('张.{1,2}','张英和张飞和张老三子')
Out[10]: ['张英和', '张飞和', '张老三']
# 非贪婪匹配
在贪婪匹配的后面加上一个问号就可以将贪婪变成非贪婪
In [11]: res1 = '深圳-乌鲁木齐3天2晚 | 入住大连黄金山大酒店 + 南方航空/东海往返机票'
In [12]: re.findall('-(.*?)\d+',res1)
Out[12]: ['乌鲁木齐']
In [13]: re.findall('-(.*)\d+',res1)
Out[13]: ['乌鲁木齐3天']
# 你们只需要将.*和.*?搞明白就可以了
In [14]: res = '<script>111</script>'
In [15]: re.findall('<.*>',res)
Out[15]: ['<script>111</script>']
In [16]: re.findall('<.*?>',res)
Out[16]: ['<script>', '</script>']
In [17]: re.findall('^<.*?>',res)
Out[17]: ['<script>']
In [18]: re.findall('<.*?>\d',res)
Out[18]: ['<script>1']
In [19]: re.findall('(<.*?>)\d',res)
Out[19]: ['<script>']
"""
问号跟在量词后面就是取消贪婪匹配
直接跟在正则表达式后面就是量词的意思
"""
re模块下的三个方法
re.findall()
使用较多
re.serach()
匹配到一个就结束
re.match()
从头匹配 头部不符合直接不匹了
在数据分析环境下可以使用
str.extract()书写正则
为了舒适的结果,眼前的坎坷路程即使再长都是值得的。