飞道的博客

【Kaggle纽约出租车车程用时预测实战(1)】Pandas读取和处理多种类型格式数据

219人阅读  评论(0)

1、导入要使用的库

这里需要有前期机器学习和数据分析的基础,设置程序运行的路径和忽略警报提醒

import os
os.chdir(r'C:\Users\86177\Desktop\taxi')
import warnings
warnings.filterwarnings('ignore')
import pandas as pd
from datetime import datetime, date
from dateutil.parser import parse
from sklearn.model_selection import train_test_split
import xgboost as xgb
from sklearn.linear_model import LinearRegression, Ridge,BayesianRidge
from sklearn.cluster import MiniBatchKMeans
from sklearn.metrics import mean_squared_error
from math import radians, cos, sin, asin, sqrt
import seaborn as sns
import matplotlib
import numpy as np
import matplotlib.pyplot as plt
plt.rcParams['figure.figsize'] = [60, 30]
from sklearn.cluster import KMeans
from sklearn.model_selection import GridSearchCV
from sklearn.model_selection import cross_val_score, KFold
print('Models loaded completely!')

–> 输出的结果为:

Models loaded completely!

2、数据导入及查看

2.1 加载训练数据和测试数据

因为'pickup_datetime'是时间特征,可以使用pandas中自带的解析方法,直接将数据转化为datetime数据

train = pd.read_csv('train.csv', parse_dates=['pickup_datetime'])
test = pd.read_csv('test.csv', parse_dates=['pickup_datetime'])
print( ' train shape:{}, columns:{} '.format(train.shape,train.columns))
print( ' test shape:{}, columns:{}'.format(test.shape,test.columns))

print(train['pickup_datetime'].head())
print(train.columns)

–> 输出的结果为:(数据量有些大,如果直接用Excel打开,数据是没办法全部加载的)

train shape:(1458644, 11)
test shape:(625134, 9)

0   2016-03-14 17:24:55
1   2016-06-12 00:43:35
2   2016-01-19 11:35:24
3   2016-04-06 19:32:31
4   2016-03-26 13:30:55
Name: pickup_datetime, dtype: datetime64[ns]

['id', 'vendor_id', 'pickup_datetime', 'dropoff_datetime', 'passenger_count', 'pickup_longitude',
 'pickup_latitude', 'dropoff_longitude', 'dropoff_latitude', 'store_and_fwd_flag', 'trip_duration']

2.2 查看一下缺少的两个特征值

由于特征值的名称即为DataFramecolumns中的名称,处理的方法就有两种,第一种就是,从test数据中遍历columns,如果这个内容不属于traincolumns的内容就可以打印输出;第二种就是很简单的集合去重的功能

1)方法一,遍历test数据,提取不在train中的数据

print([i for i in train.columns if i not in test.columns])

输出的结果为:

['dropoff_datetime', 'trip_duration']

2)方法二、集合去重(推荐)

print(list(set(train.columns) - set(test.columns)))

输出的结果为:

['dropoff_datetime', 'trip_duration']

★★★ 3)为什么test数据集中比train数据集中少两个特征?

首先看一下这两个特征代表的意义:第一个参数代表着出租车到达的时间,而第二个参数是出租车的行程时间。结合项目的出发点,也就是用来进行纽约出租车车程的预测,那么肯定是要根据train数据上已经有的数据(出发、到达以及行程时间)来预测test上未有的(只提供了出发时间,就要预测到达时间,那么行程时间也就自然得到了)

3、加载假日信息

3.1 直接加载数据

出租车的运行繁忙程度与节假日有着密切的联系,可以考虑在数据处理的过程中加入节假日相关的数据

holiday = pd.read_csv('NYC_2016Holidays.csv',sep=';')
print(holiday.head())

输出的结果为:(美国的节假日,这里的数据不是以逗号分隔,而是以分号分隔的)


	Day			Date		Holiday
0	Friday	January 01		New Years Day
1	Monday	January 18		Martin Luther King Jr. Day
2	Friday	February 12		Lincoln's Birthday
3	Monday	February 15		Presidents' Day
4	Sunday	May 08			Mother's Day

3.2 在date字段加入年份

这里对DataFrame某一字段的内容进行操作也有两种方式,一种是比较容易想到的map函数函数下使用其str方法,还有一种是使用其apply的进阶用法

1) 处理DataFrame中的文本数据

holiday['Date'] = list(map(lambda x: x+' 2016',holiday['Date'].str[:]))
print(holiday.head())

输出的结果为:(关于map函数的使用方法)

	Day		Date				Holiday
0	Friday	January 01 2016		New Years Day
1	Monday	January 18 2016		Martin Luther King Jr. Day
2	Friday	February 12 2016	Lincoln's Birthday
3	Monday	February 15 2016	Presidents' Day
4	Sunday	May 08 2016			Mother's Day

2) 使用DataFrame中的apply的进阶用法

holiday['Date'] = holiday['Date'].apply(lambda x: x + ' 2016')
print(holiday.head())

输出的结果为:(这两种方法使用一种即可)

	Day		Date				Holiday
0	Friday	January 01 2016		New Years Day
1	Monday	January 18 2016		Martin Luther King Jr. Day
2	Friday	February 12 2016	Lincoln's Birthday
3	Monday	February 15 2016	Presidents' Day
4	Sunday	May 08 2016			Mother's Day

3.3 将Date数据转化为Datetime类型数据

这里就是涉及到时间字段格式化的处理,在之前的数据分析中已经有讲到,还可以使用之前的解析方法(可以参考【python数据分析(15)】博客中的内容)

1)直接使用时间字段转datetime的方法

holidays = [datetime.strptime(holiday.loc[i,'Date'], '%B %d %Y').date() for i in range(len(holiday))]
print(holidays)

输出的结果为:

[datetime.date(2016, 1, 1),
 datetime.date(2016, 1, 18),
 datetime.date(2016, 2, 12),
 datetime.date(2016, 2, 15),
 datetime.date(2016, 5, 8),
 datetime.date(2016, 5, 30),
 datetime.date(2016, 6, 19),
 datetime.date(2016, 7, 4),
 datetime.date(2016, 9, 5),
 datetime.date(2016, 10, 10),
 datetime.date(2016, 11, 11),
 datetime.date(2016, 11, 24),
 datetime.date(2016, 12, 26),
 datetime.date(2016, 7, 4),
 datetime.date(2016, 11, 8)]

2) 利用parse方法进行时间字段向datetime数据转化

holidays = [parse(holiday.loc[i,'Date']).date() for i in range(len(holiday))]
print(holidays)

输出的结果为:(推荐的方式)

[datetime.date(2016, 1, 1),
 datetime.date(2016, 1, 18),
 datetime.date(2016, 2, 12),
 datetime.date(2016, 2, 15),
 datetime.date(2016, 5, 8),
 datetime.date(2016, 5, 30),
 datetime.date(2016, 6, 19),
 datetime.date(2016, 7, 4),
 datetime.date(2016, 9, 5),
 datetime.date(2016, 10, 10),
 datetime.date(2016, 11, 11),
 datetime.date(2016, 11, 24),
 datetime.date(2016, 12, 26),
 datetime.date(2016, 7, 4),
 datetime.date(2016, 11, 8)]

4、 加载行程具体的信息

之前加载的数据中不是很详尽,这里再进行数据的补充。数据中包含了车程的总距离,花费的时间以及遇到了路口和具体的转向,由于数据集较大,数据分为两部分,因为需要先把数据加载后合并(两个表的合并属于横向连接,使用pd.concat的方法)

4.1 加载数据并查看

fastrout1 = pd.read_csv('fastest_routes_train_part_1.csv',
                        usecols=['id', 'total_distance', 'total_travel_time',  'number_of_steps','step_direction'])
fastrout2 = pd.read_csv('fastest_routes_train_part_2.csv',
                        usecols=['id', 'total_distance', 'total_travel_time',  'number_of_steps','step_direction'])
fastrout = pd.concat((fastrout1,fastrout2))
print(fastrout.head())

输出的结果为:(后四项数据分别对应上面的介绍)


	id	 total_distance	total_travel_time number_of_steps	step_direction
0	id2875421	2009.1		164.9				5			left|straight|right|straight|arrive
1	id2377394	2513.2		332.0				6			none|right|left|right|left|arrive
2	id3504673	1779.4		235.8				4			left|left|right|arrive
3	id2181028	1614.9		140.1				5			right|left|right|left|arrive
4	id0801584	1393.5		189.4				5			right|right|right|left|arrive

4.2 处理step_direction字段的数据

这里可以把right和left的数据单独提取出来,注意里面还存在slight rightslight left,这种是需要去掉的,这里的处理和之前添加年份的字段处理类似,都是对于某一字段中数据提取,可以使用map()方法,也可以使用apply进阶方式

right_turn = list(map(lambda x:x.count('right')-x.count('slight right'),fastrout.step_direction))
left_turn = list(map(lambda x:x.count('left')-x.count('slight left'),fastrout.step_direction))
#这两种方法选择一种即可
#right_turn = fastrout['step_direction'].apply(lambda x:x.count('right')-x.count('slight right'))
#left_turn = fastrout['step_direction'].apply(lambda x:x.count('left')-x.count('slight left'))

然后将这两个字段数据添加到原来的数据中,代替step_direction字段的数据,关于添加字段的方法也是有两种,之前一直使用的是df[‘字段名’] = data, 也可以使用pd.assign(data = data)的方式

osrm_data = fastrout[['id','total_distance','total_travel_time','number_of_steps']]
osrm_data = osrm_data.assign(right_steps=right_turn)
osrm_data = osrm_data.assign(left_steps=left_turn)
#或者使用以往的方法
#osrm_data['right_steps'] = right_turn
#osrm_data['left_steps'] = left_turn
osrm_data.head()

输出的结果为:


	id		total_distance	total_travel_time	number_of_steps	right_steps	left_steps
0	id2875421	2009.1			164.9				5				1			1
1	id2377394	2513.2			332.0				6				2			2
2	id3504673	1779.4			235.8				4				1			2
3	id2181028	1614.9			140.1				5				2			2
4	id0801584	1393.5			189.4				5				3			1

4.3 按照同样的方式处理test数据

osrm_test = pd.read_csv('fastest_routes_test.csv')
right_turn= list(map(lambda x:x.count('right')-x.count('slight right'),osrm_test.step_direction))
left_turn = list(map(lambda x:x.count('left')-x.count('slight left'),osrm_test.step_direction))

osrm_test = osrm_test[['id','total_distance','total_travel_time','number_of_steps']]
osrm_test = osrm_test.assign(right_steps=right_turn)
osrm_test = osrm_test.assign(left_steps=left_turn)
osrm_test.head()

输出的结果为:(除了target(标签)字段外,测试数据和训练数据的样式要一致,否则模型不具有预测的能力)

		id	total_distance	total_travel_time	number_of_steps	right_steps	left_steps
0	id0771704	1497.1			200.2				7				2			3
1	id3274209	1427.1			141.5				2				0			0
2	id2756455	2312.3			324.6				9				4			4
3	id3684027	931.8			84.2				4				2			1
4	id3101285	2501.7			294.7				8				3			3

5、天气数据的加载

天气情况对于出租车运行也会产生影响,因此也可以将天气的数据考虑进去,其中的time字段可以直接转化为datetime数据

weather = pd.read_csv('KNYC_Metars.csv', parse_dates=['Time'])
print(weather.head())

输出的结果为:

至此,所有的数据全部加载完成,接下来就是进行数据可视化


转载:https://blog.csdn.net/lys_828/article/details/104741972
查看评论
* 以上用户言论只代表其个人观点,不代表本网站的观点或立场