写在开头:这一节的内容是根据家庭作业来的,我们会对家庭作业中的问题展开的进行代码的运行与讲解,然后将代码进行封装直接跑出所有程序,数据的话会放在百度网盘以供下载。
航空公司数据匹配
今天要完成的一个小任务就是利用pandas去匹配航空公司数据,会给定几个简单的题目,然后对每个任务分别进行完成。首先呢我们需要对数据的字符段进行说明。
数据段说明
变量名 | 解释说明 |
---|---|
year、month、day | 起飞日期 |
dep_time、arr_time | 起飞(departure)时间和到达时间。格式:HHMM,当地时间。 |
sched_dep_time、sched_arr_time | 计划起飞时间、计划到达时间 |
dep_delay、arr_delay | 起飞延误、到达延误 |
hour、minute | 计划起飞时间拆分为 hour 和 minute |
carrier | 承运商缩写 |
tailnum | 飞机尾号 |
origin、dest | 始发地、目的地 |
airtime | 空中时间 |
distance | 机场间距 |
未说明数据可以忽略。
问题展示
问题 | 内容 |
---|---|
问题1a | 寻找达到延误2小时或者更多的航班 |
问题1b | 寻找飞往IAH或HOU机场的航班 |
问题1c | 寻找联合航空、美利坚航空和三角洲航空的航班 |
问题1d | 寻找7、8、9月的航班 |
问题1e | 寻找到达延误2小时但出发时间没有延误的航班 |
问题1f | 寻找延误1小时但飞行弥补30分钟的航班的航班 |
问题2 | 计算每驾飞机在第一次延误超过1小时前的飞行次数 |
问题3 | 找到至少两个航空公司直达的目的地,并且对该目的地根据航班数对航空公司进行排序 |
问题4 | 验证是否每架飞机只属于一个航空公司 |
问题解答
下面跟着笔者的思路一道题一道题的完成问题吧,当然每个题的解不唯一,
数据查看
在进行研究前我们先来加载数据,然后看一看数据逇整体信息,
import os
import pandas as pd
import numpy as np
os.chdir('C:\\Users\\Hsm\\Desktop\\数据\\fixtures')
flights = pd.read_csv("flights.csv")
print("1.查看数据规模")
print(flights.shape) #观察数据规模
print("-"*40)
print("\n2.查看变量名")
print(flights.columns) #观察数据变量名
print("-"*40)
print("\n3.查看数据基本信息")
flights.info() #观察变量数量与类型
print("-"*40)
flights.drop_duplicates() #重复值处理
print("\n4.统计缺失值") #缺失值统计查看
nulls = np.sum(flights.isnull())
nullcols = nulls.loc[(nulls != 0)]
print(nullcols)
print("这里有",len(nullcols),"个变量存在缺失值")
1.查看数据规模
(336776, 19)
----------------------------------------
2.查看变量名
Index(['year', 'month', 'day', 'dep_time', 'sched_dep_time', 'dep_delay',
'arr_time', 'sched_arr_time', 'arr_delay', 'carrier', 'flight',
'tailnum', 'origin', 'dest', 'air_time', 'distance', 'hour', 'minute',
'time_hour'],
dtype='object')
----------------------------------------
3.查看数据基本信息
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 336776 entries, 0 to 336775
Data columns (total 19 columns):
year 336776 non-null int64
month 336776 non-null int64
day 336776 non-null int64
dep_time 328521 non-null float64
sched_dep_time 336776 non-null int64
dep_delay 328521 non-null float64
arr_time 328063 non-null float64
sched_arr_time 336776 non-null int64
arr_delay 327346 non-null float64
carrier 336776 non-null object
flight 336776 non-null int64
tailnum 334264 non-null object
origin 336776 non-null object
dest 336776 non-null object
air_time 327346 non-null float64
distance 336776 non-null float64
hour 336776 non-null float64
minute 336776 non-null float64
time_hour 336776 non-null object
dtypes: float64(8), int64(6), object(5)
memory usage: 48.8+ MB
----------------------------------------
4.统计缺失值
dep_time 8255
dep_delay 8255
arr_time 8713
arr_delay 9430
tailnum 2512
air_time 9430
dtype: int64
这里有 6 个变量存在缺失值
这里需要注意的是缺失值,这意味着我们在后面进行匹配是有必要考虑缺失情况进行补充。
问题1a
寻找达到延误2小时或者更多的航班
"""
要求:到达延误2小时或更多的航班
思路:寻找arr_delay大于120的航班,或者到达时间比预计达到时间多120分钟以上的航班(因为有航班延误数据缺失)
"""
arr2 = flights[flights['arr_delay'] >= 120] #选择延误arr_delay指标大于2小时的
arr2_na = flights[(flights['arr_delay'].isnull())] #指定arr_delay指标为空的数据,在其中进行寻找
arr2_na = arr2_na[arr2_na['arr_time']-arr2_na['sched_arr_time'] >= 200] #通过到达时间减去预计到达时间来判断是否延误两小时以上
#########################
#注意:
#考虑到如果存在00:05到达而预计23:30到达的航班,需要对时间进行咵天处理。反之也是如此
#但是由于缺失arr_delay数据中不存在类似于上述的咵天处理情况,因此直接使用到达与预计到达时间差作为判断指标是可行的
#########################
answer = pd.concat((arr2, arr2_na), axis=0) #将两段数据进行连接
answer.iloc[:5]
问题1b
寻找飞往IAH或HOU机场的航班
"""
要求:寻找到达威廉·佩特斯·霍比机场(HOU)和乔治·布什洲际机场(IAH)的航班
思路:首先去掉停飞的航班(无起飞时间dep_time),然后对dest进行匹配
"""
dest_flights = flights.dropna(axis = 0, subset = ['dep_time']) #删除停飞航班信息
answer = dest_flights[
(dest_flights['dest'] == 'HOU') |
(dest_flights['dest'] == 'IAH')
]
answer.iloc[:5]
问题1c
寻找联合航空(UA)、美利坚航空(AA)和三角洲航空(DL)的航班
"""
要求:寻找来自联合航空(UA)、美利坚航空(AA)、三角洲航空(DL)的航班
思路:首先去掉停飞的航班(无起飞时间dep_time),然后对carrier进行匹配
"""
carrier_flights = flights.dropna(subset = ['dep_time'])
answer = carrier_flights[
(carrier_flights['carrier'] == 'UA') |
(carrier_flights['carrier'] == 'AA') |
(carrier_flights['carrier'] == 'DL')
]
answer.iloc[:5]
问题1d
寻找7、8、9月的航班
"""
要求:寻找7月、8月、9月出发的航班
思路:首先去掉停飞的航班(无起飞时间dep_time),观察到数据最多为9月,于是匹配大于等于7月出发的即可
"""
month_flights = flights.dropna(subset = ['dep_time'])
answer = month_flights[
(7 <= month_flights['month']) &
(month_flights['month'] <= 9)
]
answer.iloc[:5]
问题1e
寻找到达延误2小时但出发时间没有延误的航班
"""
要求:寻找到达延误超过两小时,但出发没有延误的航班
思路:调用到达延误超过两小时函数,然后搜索出发延误dep_delay<=0的航班
"""
arr2 = flights[flights['arr_delay'] >= 120]
arr2_na = flights[(flights['arr_delay'].isnull())]
arr2_na = arr2_na[arr2_na['arr_time']-arr2_na['sched_arr_time'] >= 200]
answer = pd.concat((arr2, arr2_na), axis=0)
data = answer #调用延误超过两小时函数
data[data['dep_delay'].isnull()] #查看达延误超过两小时航班中有无缺失出发延误dep_delay的数据
answer1 = data[data['dep_delay'] <= 0]
answer1.iloc[:5]
问题1f
寻找延误1小时但飞行弥补30分钟的航班的航班
"""
要求:寻找出发延误至少一小时但飞行过程中弥补了30分钟的航班
思路:寻找dep_delay>=60的航班为出发延误至少一小时,然后寻找arr_delay与dep_delay差值<=30的航班认为弥补了至少30分钟
"""
answer = flights[
(flights['dep_delay']>=60) &
(flights['dep_delay'] - flights['arr_delay'] >=30)
]
answer.iloc[:5]
问题2
计算每驾飞机在第一次延误超过1小时前的飞行次数,这里有两种解法,可以利用列表的匹配进行判断,还可以使用groupby然后通过循环每个飞机的延迟来进行判断,
"""
方法一
要求:寻找每架飞机第一次延误一小时以前的飞行次数(不考虑航班取消情况)
思路:为了寻找到第一次延误一小时以前的飞行次数,那么应该首先寻找延误一小时的飞机有哪些,然后与原数据进行左连接
然后寻找到这些飞机第一次延误一小时的航班时间,寻找该飞机航班时间小于第一次延误一小时的航班时间,
并统计次数,即可获得每个飞机第一次延误1小时之前的飞行次数
"""
#寻找延误1小时以上的航班信息
arr1 = flights[flights['arr_delay'] >= 60] #从arr_delay已有数据中选择延误大于1小时的
arr1_na = flights[(flights['arr_delay'].isnull())]
arr1_na = arr1_na[arr1_na['arr_time']-arr1_na['sched_arr_time'] >= 100] #从arr_delay缺失数据汇总选择延误大于1小时的
arr1_all = pd.concat((arr1,arr1_na), axis=0) #整合延误数据
arr1_all['is_duplicate'] = arr1_all.duplicated(['tailnum'])
tail_list = arr1_all[arr1_all['is_duplicate'] == False] #从所有延误一小时的航班中寻找飞机第一次延误1小时的航班
tail_list_date = tail_list[['tailnum','time_hour']] #仅保存飞机尾号与航班日期信息
orgin = flights
expand_list = pd.merge(orgin, tail_list_date, on = 'tailnum', how = 'left') #将飞机尾号与航班日期与原数据表进行左连接
tail_num = expand_list[expand_list['time_hour_x'] < expand_list['time_hour_y']] #寻找出发时间在一次延误时间之前的航班
answer = pd.DataFrame(tail_num.loc[:, 'tailnum'].value_counts()) #统计每个航班出现次数
answer.iloc[:5]
tailnum
N274JB 346
N324JB 324
N247JB 317
N354JB 312
N304JB 305
"""
方法二
利用groupby将每个飞机进行区分,然后按照时间顺序排序,统计什么时候遇到延误大于60分钟的就结束
(这里因为懒就没有考虑arr_delay的缺失值)
"""
sss = flights.sort_values('time_hour', ascending=True)
ssd = sss.groupby(['tailnum'])
l = []
for name, grouped in ssd:
mean1 = ssd.get_group(name)
count = 0
for time in mean1['arr_delay']:
if time <= 60:
count += 1
else:
break
l.append((name, count))
ll = pd.DataFrame(l)
ll.columns = ['tailnum','times']
ll.iloc[:5]
tailnum times
0 D942DN 0
1 N0EGMQ 38
2 N10156 9
3 N102UW 25
4 N103US 46
问题3
找到至少两个航空公司直达的目的地,并且对该目的地根据航班数对航空公司进行排序
data = flights
data['num'] = pd.DataFrame(np.ones(flights.shape[0]).reshape(-1,1)) #增加一个用于计数的列
dest = data.groupby(['dest']) #按照dest进行分组
k = []
for index, data in dest:
if len(data['carrier'].unique()) >= 2: #判断目的地是否有大于两个航空公司直达
data_sum = data.groupby(['carrier']).sum() #计算直达的公司数量求和
data_sum = data_sum.sort_values('num', ascending=False) #按照计数项进行排序
k.append((index, list(data_sum.index))) #储存目的地,与航空公司名
answer = pd.DataFrame(k)
answer.columns = ['目的地', '航空公司']
answer.iloc[:5]
目的地 航空公司
0 ATL [DL, FL, MQ, EV, UA, 9E, WN]
1 AUS [B6, UA, AA, DL, WN, 9E]
2 AVL [EV, 9E]
3 BDL [EV, UA]
4 BGR [EV, 9E]
问题4
验证是否每架飞机只属于一个航空公司
"""
要求:判断一架飞机是否从属于一个航空公司
思路:首先对航空公司与飞机尾号进行去重,然后这是飞机尾号只属于一个公司,那么对飞机尾号进行去重,应当无重复出现。
"""
data = flights
data['duplicated'] = data.duplicated(['tailnum', 'carrier']) #对飞机尾号与航空公司去重
tail_carrier = data[data['duplicated'] == False]
tail_carrier['tail_duplicated'] = tail_carrier.duplicated(['tailnum']) #对飞机尾号进行去重
answer = tail_carrier[tail_carrier['tail_duplicated'] == True]
answer.shape[0]
23
这里出现23个值,说明有的飞机不光属于一个公司,可能是几个公司所有的,所以题目的判断是错误的。
程序打包
import os
import pandas as pd
import numpy as np
class homework_2nd():
def __init__(self):
pass
def load_data(self):
"""
修改路径加载数据
"""
os.chdir('C:\\Users\\Hsm\\Desktop\\数据\\fixtures')
flights = pd.read_csv("flights.csv")
return flights
def check_data(self, flights):
"""
产看数据规模、变量名、信息、缺失数据统计
"""
print("1.查看数据规模")
print(flights.shape) #观察数据规模
print("-"*40)
print("\n2.查看变量名")
print(flights.columns) #观察数据变量名
print("-"*40)
print("\n3.查看数据基本信息")
flights.info() #观察变量数量与类型
print("-"*40)
flights.drop_duplicates() #重复值处理
print("\n4.统计缺失值") #缺失值统计查看
nulls = np.sum(flights.isnull())
nullcols = nulls.loc[(nulls != 0)]
print(nullcols)
print("这里有",len(nullcols),"个变量存在缺失值")
def question1_a(self, flights):
"""
要求:到达延误2小时或更多的航班
思路:寻找arr_delay大于120的航班,或者到达时间比预计达到时间多120分钟以上的航班(因为有航班延误数据缺失)
"""
arr2 = flights[flights['arr_delay'] >= 120] #选择延误arr_delay指标大于2小时的
arr2_na = flights[(flights['arr_delay'].isnull())] #指定arr_delay指标为空的数据,在其中进行寻找
arr2_na = arr2_na[arr2_na['arr_time']-arr2_na['sched_arr_time'] >= 200] #通过到达时间减去预计到达时间来判断是否延误两小时以上
#########################
#注意:
#考虑到如果存在00:05到达而预计23:30到达的航班,需要对时间进行咵天处理。反之也是如此
#但是由于缺失arr_delay数据中不存在类似于上述的咵天处理情况,因此直接使用到达与预计到达时间差作为判断指标是可行的
#########################
answer = pd.concat((arr2, arr2_na), axis=0) #将两段数据进行连接
return answer
def question1_b(self, flights):
"""
要求:寻找到达威廉·佩特斯·霍比机场(HOU)和乔治·布什洲际机场(IAH)的航班
思路:首先去掉停飞的航班(无起飞时间dep_time),然后对dest进行匹配
"""
dest_flights = flights.dropna(axis = 0, subset = ['dep_time']) #删除停飞航班信息
answer = dest_flights[
(dest_flights['dest'] == 'HOU') |
(dest_flights['dest'] == 'IAH')
]
return answer
def question1_c(self, flights):
"""
要求:寻找来自联合航空(UA)、美利坚航空(AA)、三角洲航空(DL)的航班
思路:首先去掉停飞的航班(无起飞时间dep_time),然后对carrier进行匹配
"""
carrier_flights = flights.dropna(subset = ['dep_time'])
answer = carrier_flights[
(carrier_flights['carrier'] == 'UA') |
(carrier_flights['carrier'] == 'AA') |
(carrier_flights['carrier'] == 'DL')
]
return answer
def question1_d(self, flights):
"""
要求:寻找7月、8月、9月出发的航班
思路:首先去掉停飞的航班(无起飞时间dep_time),然后直接匹配月份即可
"""
month_flights = flights.dropna(subset = ['dep_time'])
answer = month_flights[
(7 <= month_flights['month']) &
(month_flights['month'] <= 9)
]
return answer
def question1_e(self, flights):
"""
要求:寻找到达延误超过两小时,但出发没有延误的航班
思路:调用到达延误超过两小时函数,然后搜索出发延误dep_delay<=0的航班
"""
data = self.question1_a(flights) #调用延误超过两小时函数
data[data['dep_delay'].isnull()] #查看达延误超过两小时航班中有无缺失出发延误dep_delay的数据
answer = data[data['dep_delay'] <= 0]
return answer
def question1_f(self, flights):
"""
要求:寻找出发延误至少一小时但飞行过程中弥补了30分钟的航班
思路:寻找dep_delay>=60的航班为出发延误至少一小时,然后寻找arr_delay与dep_delay差值<=30的航班认为弥补了至少30分钟
"""
answer = flights[
(flights['dep_delay']>=60) &
(flights['dep_delay'] - flights['arr_delay'] >=30)
]
return answer
def question2(self, flights):
"""
要求:寻找每架飞机第一次延误一小时以前的飞行次数(不考虑航班取消情况)
思路:为了寻找到第一次延误一小时以前的飞行次数,那么应该首先寻找延误一小时的飞机有哪些,然后与原数据进行左连接
然后寻找到这些飞机第一次延误一小时的航班时间,寻找该飞机航班时间小于第一次延误一小时的航班时间,
并统计次数,即可获得每个飞机第一次延误1小时之前的飞行次数
"""
#寻找延误1小时以上的航班信息
arr1 = flights[flights['arr_delay'] >= 60] #从arr_delay已有数据中选择延误大于1小时的
arr1_na = flights[(flights['arr_delay'].isnull())]
arr1_na = arr1_na[arr1_na['arr_time']-arr1_na['sched_arr_time'] >= 100] #从arr_delay缺失数据汇总选择延误大于1小时的
arr1_all = pd.concat((arr1,arr1_na), axis=0) #整合延误数据
arr1_all['is_duplicate'] = arr1_all.duplicated(['tailnum'])
tail_list = arr1_all[arr1_all['is_duplicate'] == False] #从所有延误一小时的航班中寻找飞机第一次延误1小时的航班
tail_list_date = tail_list[['tailnum','time_hour']] #仅保存飞机尾号与航班日期信息
orgin = flights
expand_list = pd.merge(orgin, tail_list_date, on = 'tailnum', how = 'left') #将飞机尾号与航班日期与原数据表进行左连接
tail_num = expand_list[expand_list['time_hour_x'] < expand_list['time_hour_y']] #寻找出发时间在一次延误时间之前的航班
answer = pd.DataFrame(tail_num.loc[:, 'tailnum'].value_counts()) #统计每个航班出现次数
return answer
def question3(self, flights):
"""
要求:寻找至少有两个航空公司去的目的地,并且根据公司航班数排出每个目的地航空公司排名
思路:利用groupby函数对目的地进行分割,然后再次利用groupby函数对航空公司进行分割,
对有两个以上航空公司去的目的地统计其航班次数并排序
"""
data = flights
data['num'] = pd.DataFrame(np.ones(flights.shape[0]).reshape(-1,1)) #增加一个用于计数的列
dest = data.groupby(['dest']) #按照dest进行分组
k = []
for index, data in dest:
if len(data['carrier'].unique()) >= 2: #判断目的地是否有大于两个航空公司直达
data_sum = data.groupby(['carrier']).sum() #计算直达的公司数量求和
data_sum = data_sum.sort_values('num', ascending=False) #按照计数项进行排序
k.append((index, list(data_sum.index))) #储存目的地,与航空公司名
answer = pd.DataFrame(k)
answer.columns = ['目的地', '航空公司']
return answer
def question4(self, flights):
"""
要求:判断一架飞机是否从属于一个航空公司
思路:首先对航空公司与飞机尾号进行去重,然后这是飞机尾号只属于一个公司,那么对飞机尾号进行去重,应当无重复出现。
"""
data = flights
data['duplicated'] = data.duplicated(['tailnum', 'carrier']) #对飞机尾号与航空公司去重
tail_carrier = data[data['duplicated'] == False]
tail_carrier['tail_duplicated'] = tail_carrier.duplicated(['tailnum']) #对飞机尾号进行去重
answer = tail_carrier[tail_carrier['tail_duplicated'] == True]
return answer
if __name__ == "__main__":
pd.set_option('display.max_columns',10)
pd.set_option('display.max_columns',5)
pd.set_option('expand_frame_repr', False)
#显示所有行
homework = homework_2nd()
flights = homework.load_data()
Q1_a = homework.question1_a(flights)
print("\n第一题的问题a:")
print("到达延误两小时的航班有%d次"%Q1_a.shape[0])
print(Q1_a)
print("-"*20)
Q1_b = homework.question1_b(flights)
print("\n第一题的问题b:")
print("飞往HOU与IAH的航班有%d次"%Q1_b.shape[0])
print(Q1_b)
print("-"*20)
Q1_c = homework.question1_c(flights)
print("\n第一题的问题c:")
print("联合航空、美利坚航空、三角洲航空公司的航班有%d次"%Q1_c.shape[0])
print(Q1_c)
print("-"*20)
Q1_d = homework.question1_d(flights)
print("\n第一题的问题d:")
print("夏季出发的航班航班有%d次"%Q1_d.shape[0])
print(Q1_d)
print("-"*20)
Q1_e = homework.question1_e(flights)
print("\n第一题的问题e:")
print("到达延误两小时但出发未延误的航班有%d次"%Q1_e.shape[0])
print(Q1_e)
print("-"*20)
Q1_f = homework.question1_f(flights)
print("\n第一题的问题f:")
print("延误一小时但到达弥补了30分钟的航班有%d次"%Q1_f.shape[0])
print(Q1_f)
print("-"*20)
Q2 = homework.question2(flights)
print("\n第二题:")
print("航班第一次延误一小时之前的航班数%d次"%Q2.shape[0])
print(Q2)
print("-"*20)
Q3 = homework.question3(flights)
print("\n第三题:")
print("目的地航空公司排名(从左往右依次变小)")
print(Q3)
print("-"*20)
Q4 = homework.question4(flights)
print("\n第四题:")
print("飞机是否属于同一个公司?")
if Q4.shape[0] == 0:
print("回答:每一架飞机都只属于一个航空公司")
else:
print("回答:每一架飞机不只属于一个航空公司")
结语
今天关于pandas对于航空公司数据的练习就到这里结束了,对于pandas的使用个还不是很熟悉,会在后面不断学习的。
谢谢阅读。
数据下载地址:
链接:https://pan.baidu.com/s/1gbhLLo307TcL_OV2_sYBhw
提取码:tt7d