简介
到这里了,我非常想吐槽这本书一下,这本书在环境部署部分显得极其简陋,存在许多不足之处。内容远古,爬虫相关的相关示例基本失效,模块拆分得也不够合理,导致初学者在学习时难以理解上下文的联系。另外,对于处理爬虫获取的离线数据,竟然引入了 Apache Flume,这与处理爬取下来数据并无太大关系。书中介绍了一堆组件,但大多数操作都非常基础,流程设计也显得十分简陋,实在令人失望。
更让我感到困惑的是,在 Pandas 数据处理部分更是重量级,写了非常繁琐的内容,真是丈二金刚摸不着头脑。对于正在学习的同学们,我建议:重点关注爬虫部分,它可以作为一个入门的小练习。同时,建议大家参考网上的资料,深入学习一下大数据组件相关环境部署及这些组件的基本用法。(可以参考我的大数据组件部署专栏)对于处理这种离线小型数据,使用 Python 是个不错的选择,至于其他部分,可以根据个人兴趣决定是否深入学习。
课本源码
代码语言:python代码运行次数:0复制import pandas as pd
# 读取 CSV 文件,指定分隔符、编码和列名
bus_info = pd.read_csv('./Beijing_Bus_Info.csv',
delimiter = ',', # 使用逗号作为分隔符
encoding = 'UTF-8', # 文件编码为 UTF-8
names = ['线路名称', '线路类型', '运行时间', '票价信息', '所属公司',
'更新时间', '总里程', '往线名称', '往线站台详细信息', '返线名称', '返线站台详细信息'])
# 删除重复的行,并重置索引
bus_info1 = bus_info.drop_duplicates().reset_index().drop('index', axis=1)
# 删除包含缺失值的行,并重置索引
bus_info2 = bus_info1.dropna().reset_index().drop('index', axis=1)
# 对总里程的数据进行清洗
for i in range(len(bus_info2['总里程'].values)):
# 检查总里程信息是否包含 '|'
if '|' in bus_info2['总里程'][i]:
# 如果包含,将其分割并取第一个部分
bus_info2['总里程'][i] = bus_info2['总里程'][i].split('|')[0]
# 如果包含'咨询',则取分割后的第一部分,直到句号
if '咨询' in bus_info2['总里程'][i]:
bus_info2['总里程'][i] = bus_info2['总里程'][i].split('。')[0]
# 如果包含 '线路咨询'
elif '线路咨询' in bus_info2['总里程'][i]:
# 分割并取第一个部分
bus_info2['总里程'][i] = bus_info2['总里程'][i].split('线路咨询')[0]
# 如果清洗后的结果为空,则标记为'没有标识'
if bus_info2['总里程'][i] == '':
bus_info2['总里程'][i] = '没有标识'
# 如果包含'低峰间隔',则取句号前的部分
elif '低峰间隔' in bus_info2['总里程'][i]:
bus_info2['总里程'][i] = bus_info2['总里程'][i].split('。')[0]
# 如果包含'间隔',则取第二个句号后的部分
elif '间隔' in bus_info2['总里程'][i]:
bus_info2['总里程'][i] = bus_info2['总里程'][i].split('。')[1]
# 检查是否包含特定关键字
elif ('本线路' in bus_info2['总里程'][i] or
'南沟村' in bus_info2['总里程'][i] or
'定点班车' in bus_info2['总里程'][i]):
bus_info2['总里程'][i] = '没有标识'
# 如果总里程包含 '线路'
elif '线路' in bus_info2['总里程'][i]:
# 如果包含'工作日',取句号后的部分
if '工作日' in bus_info2['总里程'][i]:
bus_info2['总里程'][i] = bus_info2['总里程'][i].split('工作日')[0]
bus_info2['总里程'][i] = bus_info2['总里程'][i].split('。')[1]
# 如果包含特定数字'52',则取句号后的第二部分
elif '52' in bus_info2['总里程'][i]:
bus_info2['总里程'][i] = bus_info2['总里程'][i].split('。')[1]
else:
# 否则取句号前的部分
bus_info2['总里程'][i] = bus_info2['总里程'][i].split('。')[0]
# 如果不包含'全程',则标记为'没有标识'
if '全程' not in bus_info2['总里程'][i]:
bus_info2['总里程'][i] = '没有标识'
else:
# 对于其他情况,取句号前的部分
bus_info2['总里程'][i] = bus_info2['总里程'][i].split('。')[0]
if '全程' not in bus_info2['总里程'][i]:
bus_info2['总里程'][i] = '没有标识'
# 将清洗后的数据保存到新的 CSV 文件中
bus_info2.to_csv('./Cleaned_Beijing_Bus_Info01.csv', index=False, encoding='UTF-8')
课本写法改良
代码语言:python代码运行次数:0复制import pandas as pd
# 读取 CSV 文件
# 使用 pandas 的 read_csv 函数读取名为 'Beijing_Bus_Info.csv' 的文件
# delimiter 参数指定分隔符为逗号,encoding 参数指定文件编码为 UTF-8
# names 参数指定每一列的名称,覆盖 CSV 文件中的列名
bus_info = pd.read_csv('./Beijing_Bus_Info.csv',
delimiter = ',', # 使用逗号作为分隔符
encoding = 'UTF-8', # 文件编码为 UTF-8
names = ['线路名称', '线路类型', '运行时间', '票价信息', '所属公司',
'更新时间', '总里程', '往线名称', '往线站台详细信息', '返线名称', '返线站台详细信息'])
# 去重并重置索引
# drop_duplicates 方法用于去除数据中的重复行
# reset_index 方法用于重置索引,drop=True 表示不保留原来的索引
bus_info1 = bus_info.drop_duplicates().reset_index(drop=True)
# 去掉缺失值并重置索引
# dropna 方法用于去除包含缺失值的行
# reset_index 方法用于重置索引,drop=True 表示不保留原来的索引
bus_info2 = bus_info1.dropna().reset_index(drop=True)
# 清洗“总里程”列
def clean_distance(distance):
# 如果存在 '|' 则分割
if '|' in distance:
distance = distance.split('|')[0]
if '咨询' in distance:
distance = distance.split('。')[0]
# 如果存在 '线路咨询' 则分割
elif '线路咨询' in distance:
distance = distance.split('线路咨询')[0]
if distance == '':
distance = '没有标识'
elif '低峰间隔' in distance or '间隔' in distance:
distance = distance.split('。')[0] # 处理低峰间隔
# 如果存在特定关键词,则标记为 '没有标识'
elif ('本线路' in distance or '南沟村' in distance or '定点班车' in distance):
distance = '没有标识'
# 如果存在 '线路' 则进一步处理
elif '线路' in distance:
if '工作日' in distance:
distance = distance.split('工作日')[0].split('。')[1]
elif '52' in distance:
distance = distance.split('。')[1]
else:
distance = distance.split('。')[0]
if '全程' not in distance:
distance = '没有标识'
else:
distance = distance.split('。')[0]
if '全程' not in distance:
distance = '没有标识'
return distance
# 应用清洗函数
# apply 方法将 clean_distance 函数应用到 '总里程' 列的每一个元素上
bus_info2['总里程'] = bus_info2['总里程'].apply(clean_distance)
# 将清洗完的数据保存到新的文件中
# to_csv 方法将清洗后的数据保存到名为 'Beijing_Bus_Info_Cleaned02.csv' 的文件中
# index=False 表示不保存行索引
bus_info2.to_csv('Beijing_Bus_Info_Cleaned02.csv', index=False)