项目四 pandas预处理北京公交线路

2024-09-30 07:46:37 浏览数 (1)

简介

到这里了,我非常想吐槽这本书一下,这本书在环境部署部分显得极其简陋,存在许多不足之处。内容远古,爬虫相关的相关示例基本失效,模块拆分得也不够合理,导致初学者在学习时难以理解上下文的联系。另外,对于处理爬虫获取的离线数据,竟然引入了 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)

0 人点赞