数据分析——火车信息

任务目标

任务

1、整理火车发车信息数据,结果的表格形式为:

2、并输出最终的发车信息表

难点

1、多文件

一个文件夹,多个月的发车信息,一个excel,放一天的发车情况

2、数据表的格式特殊

如何分析表是一个难点

数据形式

图像呈现

文字描述

1、一张表含多辆车次信息

2、一辆车次信息分为标题(日期、车次、定员、客座率)和表格信息部分

3、表格信息部分分为x,y轴看

横着是发车站点、发车时间、下车人数

竖着是目标站点、到达时间、上车人数

4、图标呈现下三角趋势,因为过站无上车人数

注意:

因为横着是上车站点,终点站没有人上车,所以横着的车次不包含终点站,是所有车次-1

竖着的车次包含终点站------即所有车次信息

分析步骤

1、导入数据

存在问题

与原数据不同,原数据中的表头在该表的第一列中,每个属性对应的行为空值

处理方法

处理结果

结果分析

1、38列

因为原excel表中,有车次信息到第38列,导入数据会保持表格格式完整性,所以取最大列数

不到38的列数均为空值,需要处理

2、表格信息被存放在第一行中,还需处理

3、目标需求信息只到29列的下车人数,所以需要把有效信息抠出来

语法扩展(别人的资料)

python中pandas包使用的一个header参数_header=none-CSDN博客

2、数据处理

2.1获取有效信息(扣表)

2.1.1思路分析
1、判断车次

整张表包含很多车次

要知道哪一辆车是第几行到第几行,需要拆分

(即怎么判断,eg:0-33为车1,34-45为车2,······)

2、处理表头

导入的表中有很多表头,需要处理 ,把所有车次的表头抽取出来,找共同点

都有客座率

2.1.2解决方案
1、找表头

1.1data[0]

因为数据表行列均有属性,表头均在第0列,所以先判断data[0]是第0行还是第0列

1.2找到含有"客座率"的行数

语法扩展
apply()、lambda
loc()

Pandas读取某列、某行数据------loc、iloc用法总结_pandas读取某一行的数据-CSDN博客

1.3生成由表头信息组成的表

1.4批量分割+展开表

按照空格分割后得到一个表格

split()

Python知识精解:str split()方法 - 知乎 (zhihu.com)

expand参数

pandas的分列操作str.split()_pandas数据分列-CSDN博客

2、生成除表头外的信息表

data=data[~ind]

3、生成一趟车的数据

1、根据上车站点和上车人数所在的行(用遍历匹配)

确定每一趟列车所包含的行数,再扣其中的数据

2、找第一趟车的信息

3、重置行索引

因为之前删数据把行索引删了,出现了数据缺失,需要重置行索引

drop------删除多余的一列index

4、删除空值

重置索引后的表格为

表中30列后的值均为空值,需要删除

用空值数量进行判断,若某一列中空值数量=行数,则证明该列全为空,需要删除

5、生成完整一趟车的信息表

语法扩展
loc、iloc区别

pandas索引函数loc和iloc的区别_pandas loc与iloc区别-CSDN博客

loc基于标签索引、iloc基于位置索引

reset_index()

如何在pandas中使用set_index( )与reset_index( )设置索引 - 知乎 (zhihu.com)

3、数据分析

处理后的表

3.1取表头信息表中所需数据

3.2把表头信息与每辆车挂钩

原数据(2个表)

表头表

车次表

通过索引和步长取出需要的信息行

这样就匹配成功了

3.3、取所有站点

3.4循环所有站点取数据(用定位)

都用条件筛选

3.5整体操作(合并前面操作)

语法扩展

python dataframe是什么_Pandas 库之 DataFrame-CSDN博客

4、封装函数

5、数据导出

语法扩展
glob------查找文件

Python标准库glob模块详解_python glob-CSDN博客

tpdm------进度条

【python第三方库】tqdm简介_python tqdm库-CSDN博客

enumerate() 函数

Python enumerate() 函数 | 菜鸟教程

to_csv()

pandas的to_csv()使用方法_pandas to_csv-CSDN博客

总体代码

python 复制代码
import warnings
warnings.filterwarnings('ignore')
import pandas as pd

path = './201501-201603/201501/20150101.xls'
data = pd.read_excel(path, skiprows=2, header=None)
data.head(50)

# 日期
dates = path.split('/')[-1][:8]

ind = data[0].apply(lambda x: '客座率' in x) # 筛选有车次信息的行数据
car_info = data.loc[ind, 0]
car_info = car_info.str.split(' ', expand=True) # 这里的得到车次、定员、客座率

car_info

# 删除车次信息行
data = data[~ind]
data.reset_index(inplace=True, drop=True)
data.head()

## 接下来:找到某一趟车所在的小表格,思路就是找到【上车站、上车人数合计】所在的行
ind = data[0].apply(lambda x: '上车站'==x or '上车人数合计'==x)
car_index = data[ind]

all_car = pd.DataFrame()
for start, end, checi, dingyuan, kezuolv in zip(car_index.index[0::2],car_index.index[1::2], car_info[0], car_info[6], car_info[8]):
    one_car = data.iloc[start:end+1, :] # 截取其中一趟车的数据
    one_car.reset_index(inplace=True, drop=True) # 重置索引
    col_ind = one_car.isna().sum(axis=0)==len(one_car) # 判断全为空的列
    one_car = one_car.loc[:, ~col_ind] # 删除空列
    station = one_car.iloc[2:-1, 0] # 取所有站点,在2至倒数第一行
    one_car_list = []
    for s in station: # 循环每个站点去取数据
        one_car_dict = {}
        one_car_dict['车次'] = checi
        one_car_dict['定员'] = dingyuan
        one_car_dict['客座率'] = kezuolv
        one_car_dict['日期'] = dates
        one_car_dict['站点'] = s
        one_car_dict['进站时间'] = one_car.loc[one_car[0]==s, 1].values[0] # 进站时间
        one_car_dict['下车人数'] = one_car.loc[one_car[0]==s, one_car.shape[1]-1].values[0] # 下车人数
        try:
            one_car_dict['离站时间'] = one_car.loc[1,one_car.iloc[0]==s].values[0] # 离站时间
            one_car_dict['上车人数'] = one_car.loc[len(one_car)-1,one_car.iloc[0]==s].values[0] # 上车人数
        except:
            one_car_dict['离站时间'] = '--' # 终点站没有出站时间和人数
            one_car_dict['上车人数'] = '--'
        one_car_list.append(one_car_dict)
    one_car_data = pd.DataFrame(one_car_list)
    break
    #all_car = pd.concat([all_car, one_car_data])
#这一步结束就能看到处理后表的信息了
    one_car_data

def get_one_file(path):
    data = pd.read_excel(path, skiprows=2, header=None) # 读数据
    dates = path.split('/')[-1][:8] # 日期
    ind = data[0].apply(lambda x: '客座率' in x) # 筛选有车次信息的行数据
    car_info = data.loc[ind, 0]
    car_info = car_info.str.split(' ', expand=True) # 这里的得到车次、定员、客座率
    data = data[~ind] # 删除车次信息行
    data.reset_index(inplace=True, drop=True)
    ## 接下来:找到某一趟车所在的小表格,思路就是找到【上车站、上车人数合计】所在的行
    ind = data[0].apply(lambda x: '上车站'==x or '上车人数合计'==x)
    car_index = data[ind]
    all_car = pd.DataFrame()
    for start, end, checi, dingyuan, kezuolv in zip(car_index.index[0::2],car_index.index[1::2], car_info[0], car_info[6], car_info[8]):
        one_car = data.iloc[start:end+1, :] # 截取其中一趟车的数据
        one_car.reset_index(inplace=True, drop=True) # 重置索引
        col_ind = one_car.isna().sum(axis=0)==len(one_car) # 判断全为空的列
        one_car = one_car.loc[:, ~col_ind] # 删除空列
        station = one_car.iloc[2:-1, 0] # 取所有站点,在2至倒数第一行
        one_car_list = []
        for s in station: # 循环每个站点去取数据
            one_car_dict = {}
            one_car_dict['车次'] = checi
            one_car_dict['定员'] = dingyuan
            one_car_dict['客座率'] = kezuolv
            one_car_dict['日期'] = dates
            one_car_dict['站点'] = s
            one_car_dict['进站时间'] = one_car.loc[one_car[0]==s, 1].values[0] # 进站时间
            one_car_dict['下车人数'] = one_car.loc[one_car[0]==s, one_car.shape[1]-1].values[0] # 下车人数
            try:
                one_car_dict['离站时间'] = one_car.loc[1,one_car.iloc[0]==s].values[0] # 离站时间
                one_car_dict['上车人数'] = one_car.loc[len(one_car)-1,one_car.iloc[0]==s].values[0] # 上车人数
            except:
                one_car_dict['离站时间'] = '--' # 终点站没有出站时间和人数
                one_car_dict['上车人数'] = '--'
            one_car_list.append(one_car_dict)
        one_car_data = pd.DataFrame(one_car_list)
        all_car = pd.concat([all_car, one_car_data])
    return all_car

from glob import glob
from tqdm import tqdm
all_path = glob('./201501-201603/*/*')
for i,path in tqdm(enumerate(all_path)):
    data = get_one_file(path)
    if i==0:
        data.to_csv('./result.csv', header=True, index=None, encoding='utf8', mode='a')
    else:
        data.to_csv('./result.csv', header=None, index=None, encoding='utf8', mode='a')
相关推荐
kngines2 小时前
【字节跳动】数据挖掘面试题0003:有一个文件,每一行是一个数字,如何用 MapReduce 进行排序和求每个用户每个页面停留时间
人工智能·数据挖掘·mapreduce·面试题
费弗里3 小时前
Python全栈应用开发利器Dash 3.x新版本介绍(1)
python·dash
李少兄9 天前
解决OSS存储桶未创建导致的XML错误
xml·开发语言·python
就叫飞六吧9 天前
基于keepalived、vip实现高可用nginx (centos)
python·nginx·centos
Vertira9 天前
PyTorch中的permute, transpose, view, reshape和flatten函数详解(已解决)
人工智能·pytorch·python
学Linux的语莫9 天前
python基础语法
开发语言·python
匿名的魔术师9 天前
实验问题记录:PyTorch Tensor 也会出现 a = b 赋值后,修改 a 会影响 b 的情况
人工智能·pytorch·python
Ven%9 天前
PyTorch 张量(Tensors)全面指南:从基础到实战
人工智能·pytorch·python
mahuifa9 天前
PySide环境配置及工具使用
python·qt·环境配置·开发经验·pyside
大熊猫侯佩9 天前
ruby、Python 以及 Swift 语言关于 “Finally” 实现的趣谈
python·ruby·swift