pandas数据分析航空公司数据

pandas数据分析

pandas主要有两种数据结构,分别是dataframe和series,本次我们主要讲述的是dataframe的简单应用,从数据的读取到清洗。

数据读取与观察

  • 1.pandas读取文件的方法很多,其中 read_csv() 最为常用,相对应的就有 to_csv() 方法(df调用)

  • 2.数据的观察:

    • 2.1 dataframe中,类型主要有

    • 2.2 head(),tail() :显示df的前n个记录(默认是5),显示包括列名。

    • 2.2 info(),describe(),columns :显示df的全部信息,描述,还有列名。需要注意的是, describe() 只能生成对数字的描述,Object类型无法统计描述

    • 2.4 索引:在dataframe中不能够像Numpy那样直接通过df[i]来进行索引,需要通过df[i:j]来索引具体某几行(切片操作),或者索引某一列 df['column_name'].values 来返回某一列的数值

    • 2.5 切片:切片可以通过直接 df[i:j] 来实现行切片,返回第i:j-1行,也可以通过 .iloc 来切片或者重写覆盖(用法如下)

    import csv
  import pandas
  import numpy as np
  import sklearn
  import re
  from sklearn.cluster import KMeans
  import matplotlib.pyplot as plt
  import matplotlib
  %matplotlib inline
    f = open("机票综合查询.csv")
  data = pandas.read_csv(f,encoding='utf-8')
  data.head()
  data.tail()
  print(data.index)   ## 能够返回整张表中的记录数
  data.info()   ## info() 显示数据表的基本信息
  print(data.describe().T)   ## 描述统计(基于数字)
  data[0:2]       ## 返回0:2的共2行记录(切片)
  print(data.iloc[0:3,[1,3]]) #获取1列3列的1~3行数据
  #data.iloc[0:3,[1,3]]=2       ## 把2写到选择的位置,起到覆盖作用
  passages = data["乘机人"].values   ## 通过values把返回的series变成numpyde的ndarray形式
  data.columns
    RangeIndex(start=0, stop=125011, step=1)
  <class 'pandas.core.frame.DataFrame'>
  RangeIndex: 125011 entries, 0 to 125010
  Data columns (total 7 columns):
  乘机人       124861 non-null object
  航程         124861 non-null object
  支付科目       118861 non-null object
  票面_折扣     124683 non-null float64
  票面_起飞时间   124861 non-null object
  票面_降落时间   124861 non-null object
  票面_舱位     125011 non-null object
  dtypes: float64(1), object(6)
  memory usage: 6.7+ MB
            count     mean       std min 25%   50%   75% max
  票面_折扣 124683.0 0.535882 0.358774 0.0 0.3 0.503 0.798 5.0
        航程 票面_折扣
  0 成都-南京 0.485
  1 西宁-广州 0.301
  2 广州-西宁 0.380
   
  Index(['乘机人', '航程', '支付科目', '票面_折扣', '票面_起飞时间', '票面_降落时间', '票面_舱位'], dtype='object')

3.数据筛选:

  • 3.1精确筛选:通过 isin 方法来筛选指定信息。

  • 3.2模糊筛选:通过正则表达式来进行匹配

    chose = ["成都-南京","西宁-广州"]
  result = data["航程"].isin(chose) #将要过滤的数据放入list中,使用isin对数据进行筛选,返回行索引以及每行筛选的结果,若匹配则返回ture
  data[result] ## 通过上面返回的true和false值来选出实际的行
   
  ## 模糊搜索:
  result = data["航程"].str.contains(r'-南京$')   ## 通过正则表达来实现模糊匹配
  data[result]

数据清洗:

数据清洗包括查重、去空、填充、删除、替换等操作,以下是相关函数的用法:

1.查重,去空,填充,删除,补行

在这里需要注意的是经过删除操作之后,会出现空行 ,每一行并不会自动补上,导致实际长度小于序号(序号为开始处理前的样子),需要用到 reset_index() 方法来重新排序.

    ## 把为空的数据删掉或填上默认值
  data.fillna(np.nan) ## fillna("some") 以“some”来填充空值(null)
  data = data.dropna(axis=0, how='any')       ## 丢弃空值的行
  #data.drop("航程",axis=1)     ## 在列方向(axis),删除“航程”这一列
  data["航程"]
  ## 查重:
  data["航程"].unique()   ## 对某一列进行查重,返回该列存在的元素
  data = data.drop_duplicates(subset="乘机人") ## 在指定的某列进行去重
  data = data.reset_index(drop=True)   ## 对data表重新排序,这里的drop=true表示不在表内新建一列index,而是直接补上
  data.info()
    <class 'pandas.core.frame.DataFrame'>
  RangeIndex: 36834 entries, 0 to 36833
  Data columns (total 7 columns):
  乘机人       36834 non-null object
  航程         36834 non-null object
  支付科目       36834 non-null object
  票面_折扣     36834 non-null float64
  票面_起飞时间   36834 non-null object
  票面_降落时间   36834 non-null object
  票面_舱位     36834 non-null object
  dtypes: float64(1), object(6)
  memory usage: 2.0+ MB

2.替换

  • 2.1 replace: replace() 方法能够通过字典的形式来进行直接的替换

  • 2.2 apply: apply() 方法能够通过传递一个函数进去后对每一个元素进行操作

    ## 通过字典来替换行名称,替换成英文后可以直接通过.passage 来代替["乘机人"]
  data=data.rename(columns={"乘机人":"passage","航程":"route","支付科目":"payway","票面_折扣":"discount",
                                      "票面_起飞时间":"offtime","票面_降落时间":"downtime","票面_舱位":"siteclass"})
   
  data["siteclass"].unique() ## 统计机舱位的种类
  # print(data.siteclass.value_counts()) ## 统计每个种类的个数
  change = {'W':0, 'L':1, 'E':2, 'K':3,'R':4, 'D':5, 'Z':6, 'V':7, 'Y':8, 'T':9, 'U':10, 'S':11, 'X':12, 'Q':13, 'I':14,
            'H':15,'N':16, 'M':17, 'B':18, 'P':19, 'A':20, 'G':21, 'J':22, 'C':23, 'O':24, 'F':25, 'e':2}
  data.siteclass=data.siteclass.replace(change)   ## 通过字典来把舱位数字化
   
  ##   apply 方法。
  def clasification(strings):
      if "-" in strings:
          strings = strings.replace("-","/")
      return strings
  data["offtime"]=data["offtime"].apply(clasification)

3.数据格式转换

    data.discount=data.discount.astype(float)
  ## 由字符串转换成时间序列:
  data['offtime']=pandas.to_datetime(data['offtime'], format="%Y/%m/%d %H:%M") ## format为字符串的格式
  data.info()
    <class 'pandas.core.frame.DataFrame'>
    RangeIndex: 36834 entries, 0 to 36833
    Data columns (total 7 columns):
    passage      36834 non-null object
    route        36834 non-null object
    payway       36834 non-null object
    discount     36834 non-null float64
    offtime      36834 non-null object
    downtime     36834 non-null object
    siteclass    36834 non-null object
    dtypes: float64(1), object(6)
    memory usage: 2.0+ MB

实战:

实战内容主要是以航空公司的部分资料,通过聚类算法来进行数据分析,通过飞行时间(降落时间与起飞时间的差)来间接体现飞行距离,这里就需要用把字符串的时间转换成time的格式来进行运算。

    import csv
    import pandas
    import numpy as np
    import sklearn
    import re
    from tqdm import tqdm
    from sklearn.cluster import KMeans
    import matplotlib.pyplot as plt
    import matplotlib
    %matplotlib inline
    def clasification(strings):
    #     if re.match(pattern='^\d{4}[/]\d+[/]\d+\s\d+[:]\d+',string=string)!=null:
        if "-" in strings:
            strings = strings.replace("-","/")
    #         print(strings)
        return strings
    
    
    f = open("机票综合查询.csv")
    data = pandas.read_csv(f,encoding="utf-8")
    data.info()    ## info() 显示数据表的基本信息
    data.fillna("NaN") ## fillna("some") 以“some”来填充空值(null)
    data = data.dropna(axis=0, how='any')        ## 丢弃空值的行
    data = data.reset_index(drop=True)
    drops = []
    for a,one in enumerate(data.values):
        if len(one[1].split("-"))>2 or one[1]=="#NAME?":
            drops.append(a)
    data = data.drop(drops)
    data = data.reset_index()
    data = data.drop("index",axis=1)
    print("-----------after dorping--------------")
    data=data.rename(index=str,columns={"乘机人":"passage","航程":"route","支付科目":"payway","票面_折扣":"discount",
                                        "票面_起飞时间":"offtime","票面_降落时间":"downtime","票面_舱位":"siteclass"})
    data.info()
    print("----------check siteclass----------------")
    print(data["siteclass"].unique())  ## 统计机舱位的种类
    # print(data.siteclass.value_counts())  ## 统计每个种类的个数
    change = {'W':0, 'L':1, 'E':2, 'K':3,'R':4, 'D':5, 'Z':6, 'V':7, 'Y':8, 'T':9, 'U':10, 'S':11, 'X':12, 'Q':13, 'I':14, 
              'H':15,'N':16, 'M':17, 'B':18, 'P':19, 'A':20, 'G':21, 'J':22, 'C':23, 'O':24, 'F':25, 'e':2}
    data.siteclass=data.siteclass.replace(change)
    # print(data.siteclass.value_counts())
    data["offtime"]=data["offtime"].apply(clasification)
    data['offtime']=pandas.to_datetime(data['offtime'], format="%Y/%m/%d %H:%M")
    data['downtime']=pandas.to_datetime(data['downtime'], format="%Y/%m/%d %H:%M")
    data.insert(loc=6,column="lasttime",value=0)
    data["lasttime"] = data["downtime"]-data["offtime"]       ## 增加一列,表示总共的飞行时间,间接说明飞行距离
    data.info()
    <class 'pandas.core.frame.DataFrame'>
    RangeIndex: 125011 entries, 0 to 125010
    Data columns (total 7 columns):
    乘机人        124861 non-null object
    航程         124861 non-null object
    支付科目       118861 non-null object
    票面_折扣      124683 non-null float64
    票面_起飞时间    124861 non-null object
    票面_降落时间    124861 non-null object
    票面_舱位      125011 non-null object
    dtypes: float64(1), object(6)
    memory usage: 6.7+ MB
    -----------after dorping--------------
    <class 'pandas.core.frame.DataFrame'>
    Index: 112390 entries, 0 to 112389
    Data columns (total 7 columns):
    passage      112390 non-null object
    route        112390 non-null object
    payway       112390 non-null object
    discount     112390 non-null float64
    offtime      112390 non-null object
    downtime     112390 non-null object
    siteclass    112390 non-null object
    dtypes: float64(1), object(6)
    memory usage: 6.9+ MB
    ----------check siteclass----------------
    ['W' 'L' 'E' 'K' 'R' 'D' 'Z' 'V' 'Y' 'T' 'U' 'S' 'X' 'Q' 'I' 'H' 'N' 'M'
     'B' 'P' 'A' 'G' 'J' 'C' 'O' 'F' 'e']
    <class 'pandas.core.frame.DataFrame'>
    Index: 112390 entries, 0 to 112389
    Data columns (total 8 columns):
    passage      112390 non-null object
    route        112390 non-null object
    payway       112390 non-null object
    discount     112390 non-null float64
    offtime      112390 non-null datetime64[ns]
    downtime     112390 non-null datetime64[ns]
    lasttime     112390 non-null timedelta64[ns]
    siteclass    112390 non-null int64
    dtypes: datetime64[ns](2), float64(1), int64(1), object(3), timedelta64[ns](1)
    memory usage: 12.7+ MB

以下是对数据进行聚类

KMeans 聚类:

我们本次实验主要是对航空公司的折扣以及用户飞行路程(通过飞行时间来表征)来进行聚类,并生成用户标签

    for a in data.head(5).values:
        print(a[6].seconds/60)  ## 有days,seconds属性
    disconunt = np.array(data["discount"]).reshape([-1,1])
    print(disconunt.min())
    disconunt = (disconunt - disconunt.min())/(disconunt.max()-disconunt.min())
    print(disconunt.shape)
    siteclass = np.array(data["siteclass"]).reshape([-1,1])
    # siteclass = (siteclass-siteclass.min())/(siteclass.max()-siteclass.min())
    minutes = []
    for one in data["lasttime"]:
        minutes.append(one.seconds/60.0)
    minutes = np.array(minutes).reshape([-1,1])
    minutes = (minutes-minutes.min())/(minutes.max()-minutes.min())
    tent = np.concatenate([disconunt,minutes, siteclass],axis=1)
    print(tent.shape)
    150.0
    295.0
    330.0
    160.0
    140.0
    0.0
    (112390, 1)
    (112390, 3)
    K = 4
    kmeans = KMeans(n_clusters=K)
    kmeans.fit(tent)
    label = kmeans.labels_.reshape([-1,1])
    result = np.concatenate([label,tent],axis=1)
    result[0]
    array([ 0.        ,  0.097     ,  0.10452962,  0.        ])
    from mpl_toolkits.mplot3d import Axes3D 
    fig = plt.figure()
    ax = Axes3D(fig)
    # ax.contour(X, Y, Z, 16, extend3d=True)
    
    for i in range(K):
        x=[]
        y=[]
        z=[]
        for one in result:
            if one[0]==i:
                x.append(one[1])##discount
                y.append(one[2])##minutes
                z.append(one[3])##siteclass
        z = np.array(z).reshape([1,-1])
        plt.scatter(x, y, z,c='rbgcmyk'[i])
    plt.show()

 

    fig = plt.figure()
    for i in range(K):
        x=[]
        y=[]
        z=[]
        for one in result:
            if one[0]==i:
                x.append(one[1])##discount
                y.append(one[2])##minutes
                z.append(one[3])##siteclass
        z = np.array(z).reshape([1,-1])
        plt.scatter(x, z,c='rbgcmyk'[i])
    plt.show()

 

 

posted on 2021-06-29 14:42  BabyGo000  阅读(248)  评论(0)    收藏  举报