python小练习之航空公司数据练习题(二)

写在开头:这一节的内容是根据家庭作业来的,我们会对家庭作业中的问题展开的进行代码的运行与讲解,然后将代码进行封装直接跑出所有程序,数据的话会放在百度网盘以供下载。

航空公司数据匹配

今天要完成的一个小任务就是利用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

猜你喜欢

转载自blog.csdn.net/qq_35149632/article/details/105208571