Pandas学习

Pandas学习

1. Pandas介绍
  • 2008年WesMcKinney开发出的库
  • 专门用于数据挖掘的开源python库
  • 以Numpy为基础,借力Numpy模块在计算方面性能高的优势
  • 基于matplotlib,能够简便的画图
  • 独特的数据结构
2. 为什么使用Pandas

Numpy已经能够帮助我们处理数据,能够结合matplotlib解决部分数据展示等问题,那么pandas学习的目的在什么地方呢?

  • 增强图表可读性
  • 便捷的数据处理能力
  • 读取文件方便
  • 封装了Matplotlib、Numpy的画图和计算
3. Pandas数据结构
  1. 说明

    Pandas中一共有三种数据结构,分别为:Series、DataFrame和MultiIndex(老版本中叫Panel )。

    其中Series是一维数据结构,DataFrame是二维的表格型数据结构,MultiIndex是三维的数据结构。

  2. Series
    1.Series的创建
    # 导入pandas
    import pandas as pd
    pd.Series(data=None, index=None, dtype=None)
    

    参数:

    • data:传入的数据,可以是ndarray、list等
    • index:索引,必须是唯一的,且与数据的长度相等。如果没有传入索引参数,则默认会自动创建一个从0-N的整数索引。
    • dtype:数据的类型
    # 指定内容,默认索引
    pd.Series(np.arange(10))
    # 指定索引
    pd.Series([6.7,5.6,3,10,2], index=[1,2,3,4,5])
    # 通过字典数据创建
    color_count = pd.Series({'red':100, 'blue':200, 'green': 500, 'yellow':1000})
    
    2. Series的属性

    为了更方便地操作Series对象中的索引和数据,Series中提供了两个属性index和values

    • index
      color_count = pd.Series({'red':100, 'blue':200, 'green': 500, 'yellow':1000})
      color_count.index
      # 结果
      Index(['blue', 'green', 'red', 'yellow'], dtype='object')
      
    • values

      color_count.values
      # 结果
      array([ 200,  500,  100, 1000])
      

    也可以使用索引来获取数据:

    color_count[2]
    # 结果
    100
    
  3. DataFrame

    DataFrame是一个类似于二维数组或表格(如excel)的对象,既有行索引,又有列索引

    • 行索引,表明不同行,横向索引,叫index,0轴,axis=0
    • 列索引,表明不同列,纵向索引,叫columns,1轴,axis=1 Pandas学习_第1张图片
    1. DataFrame的创建
      # 导入pandas
      import pandas as pd
      
      pd.DataFrame(data=None, index=None, columns=None)
      
      • 参数:
        • index:行标签。如果没有传入索引参数,则默认会自动创建一个从0-N的整数索引。
        • columns:列标签。如果没有传入索引参数,则默认会自动创建一个从0-N的整数索引。
      • 通过已有数据创建

      例如

      pd.DataFrame(np.random.randn(2,3))
      
      # 生成10名同学,5门功课的数据
      score = np.random.randint(40, 100, (10, 5))
      # 使用Pandas中的数据结构
      # 构造行索引序列
      subjects = ["语文", "数学", "英语", "政治", "体育"]
      # 构造列索引序列
      stu = ['同学' + str(i) for i in range(score_df.shape[0])]
      # 添加行索引
      data = pd.DataFrame(score, columns=subjects, index=stu)
      
    2. DataFrame的属性
      • shape

        data.shape
        # 结果
        (10, 5)
        
      • index:DataFrame的行索引列表

        data.index
        
        # 结果
        Index(['同学0', '同学1', '同学2', '同学3', '同学4', '同学5', '同学6', '同学7', '同学8', '同学9'], dtype='object')
        
      • columns:DataFrame的列索引列表

        data.columns
        
        # 结果
        Index(['语文', '数学', '英语', '政治', '体育'], dtype='object')
        
      • values

        data.values
        
      • T:转置

        data.T
        
      • head(5):显示前5行内容,如果不补充参数,默认5行。填入参数N则显示前N行

        data.head(5)
        
      • tail(5):显示后5行内容,如果不补充参数,默认5行。填入参数N则显示后N行

        data.tail(5)
        
    3. DatatFrame索引的设置
      1. 修改行列索引值(必须全部修改)
        stu = ["学生_" + str(i) for i in range(score_df.shape[0])]
        
        # 必须整体全部修改
        data.index = stu
        
      2. 重设索引
        • reset_index(drop=False)
          • 设置新的下标索引
          • drop:默认为False,不删除原来索引,如果为True,删除原来的索引值
        # 重置索引,drop=False
        data.reset_index()
        # 重置索引,drop=True
        data.reset_index(drop=True)
        
      3. 以某列值设置为新的索引

        set_index(keys, drop=True)

        • keys : 列索引名成或者列索引名称的列表
        • drop : boolean, default True.当做新的索引,删除原来
        df = pd.DataFrame({'month': [1, 4, 7, 10], 'year': [2012, 2014, 2013, 2014], 'sale':[55, 40, 84, 31]})
        # 以月份设置新的索引
        df.set_index('month')
        # 设置多个索引,以年和月份
        df = df.set_index(['year', 'month'])
        
  4. MultiIndex与Panel
    1. MultiIndex

      MultiIndex是三维的数据结构;

      多级索引(也称层次化索引)是pandas的重要功能,可以在Series、DataFrame对象上拥有2个以及2个以上的索引。

      1. multiIndex的特性
        # 打印上面的索引结果
        df.index
        MultiIndex(levels=[[2012, 2013, 2014], [1, 4, 7, 10]],
                   labels=[[0, 2, 1, 2], [0, 1, 2, 3]],
                   names=['year', 'month'])
        

        多级或分层索引对象。

        • index属性
          • names:levels的名称
          • levels:每个level的元素值
        df.index.names
        # FrozenList(['year', 'month'])
        
        df.index.levels
        # FrozenList([[1, 2], [1, 4, 7, 10]])
        
      2. multiIndex的创建
        arrays = [[1, 1, 2, 2], ['red', 'blue', 'red', 'blue']]
        pd.MultiIndex.from_arrays(arrays, names=('number', 'color'))
        
        # 结果
        MultiIndex(levels=[[1, 2], ['blue', 'red']],
                   codes=[[0, 0, 1, 1], [1, 0, 1, 0]],
                   names=['number', 'color'])
        
    2. Panel
      1. Panel的创建

        class pandas.Panel(data=None, items=None, major_axis=None, minor_axis=None)

        • 作用:存储3维数组的Panel结构
        • 参数:
          • data : ndarray或者dataframe
          • items : 索引或类似数组的对象,axis=0
          • major_axis : 索引或类似数组的对象,axis=1
          • minor_axis : 索引或类似数组的对象,axis=2
        p = pd.Panel(data=np.arange(24).reshape(4,3,2),
                         items=list('ABCD'),
                         major_axis=pd.date_range('20130101', periods=3),
                         minor_axis=['first', 'second'])
        
        # 结果
        <class 'pandas.core.panel.Panel'>
        Dimensions: 4 (items) x 3 (major_axis) x 2 (minor_axis)
        Items axis: A to D
        Major_axis axis: 2013-01-01 00:00:00 to 2013-01-03 00:00:00
        Minor_axis axis: first to second
        
      2. 查看panel数据

        p[:,:,"first"]
        p["B",:,:]
        
4. Pandas文件读取与存储

我们的数据大部分存在于文件当中,所以pandas会支持复杂的IO操作,pandas的API支持众多的文件格式,如CSV、SQL、XLS、JSON、HDF5, 最常用的HDF5和CSV文件 。

  1. CSV

    1. read_csv
      • pandas.read_csv(filepath_or_buffer, sep =’,’, usecols )
        • filepath_or_buffer:文件路径
        • sep :分隔符,默认用","隔开
        • usecols:指定读取的列名,列表形式
      • 举例:读取之前的股票的数据
      # 读取文件,并且指定只获取'open', 'close'指标
      data = pd.read_csv("./data/stock_day.csv", usecols=['open', 'close'])
      data.head()
      
    2. to_csv
      • DataFrame.to_csv(path_or_buf=None, sep=’, ’, columns=None, header=True, index=True, mode=‘w’, encoding=None)

        • path_or_buf :文件路径
        • sep :分隔符,默认用","隔开
        • columns :选择需要的列索引
        • header :boolean or list of string, default True,是否写进列索引值
        • index:是否写进行索引
        • mode:‘w’:重写, ‘a’ 追加
      • 举例:保存读取出来的股票数据

        • 保存’open’列的数据,然后读取查看结果
        # 选取10行数据保存,便于观察数据
        data[:10].to_csv("./data/test.csv", columns=['open'])
        # 读取,查看结果
        pd.read_csv("./data/test.csv")
        

        会发现将索引存入到文件当中,变成单独的一列数据。如果需要删除,可以指定index参数,删除原来的文件,重新保存一次。

        # index:存储不会讲索引值变成一列数据
        data[:10].to_csv("./data/test.csv", columns=['open'], index=False)
        
  2. HDF5

    需要安装安装tables模块避免不能读取HDF5文件

    pip install tables
    
    1. read_hdf与to_hdf

      HDF5文件的读取和存储需要指定一个键,值为要存储的DataFrame

      • pandas.read_hdf(path_or_buf,key =None,** kwargs)

        从h5文件当中读取数据

        • path_or_buffer:文件路径
        • key: 读取的键
        • return:Theselected object
      • DataFrame.to_hdf(path_or_buf, key, **kwargs)

    2. 案例
      # 读取文件
      day_close = pd.read_hdf("./data/day_close.h5")
      # 存储文件
      day_close.to_hdf("./data/test.h5", key="day_close")
      # 再次读取的时候, 需要指定键的名字
      new_close = pd.read_hdf("./data/test.h5", key="day_close")
      

      注意:优先选择使用HDF5文件存储

      • HDF5在存储的时候支持压缩,使用的方式是blosc,这个是速度最快的也是pandas默认支持的
      • 使用压缩可以提磁盘利用率,节省空间
      • HDF5还是跨平台的,可以轻松迁移到hadoop 上面
  3. JSON

    JSON是我们常用的一种数据交换格式,前面在前后端的交互经常用到,也会在存储的时候选择这种格式。所以我们需要知道Pandas如何进行读取和存储JSON格式。

    1. read_json

      pandas.read_json(path_or_buf=None, orient=None, typ=‘frame’, lines=False)

      • 将JSON格式准换成默认的Pandas DataFrame格式

      • orient : string,Indication of expected JSON string format.

        • ‘split’ : dict like {index -> [index], columns -> [columns], data -> [values]}

          • split 将索引总结到索引,列名到列名,数据到数据。将三部分都分开了
        • ‘records’ : list like [{column -> value}, … , {column -> value}]

          • records 以columns:values的形式输出
        • ‘index’ : dict like {index -> {column -> value}}

          • index 以index:{columns:values}...的形式输出
        • ‘columns’ : dict like {column -> {index -> value}}

          ,默认该格式

          • colums 以columns:{index:values}的形式输出
        • ‘values’ : just the values array

          • values 直接输出值
      • lines : boolean, default False

        • 按照每行读取json对象
      • typ : default ‘frame’, 指定转换成的对象类型series或者dataframe

    2. to_json

      DataFrame.to_json(path_or_buf=Noneorient=Nonelines=False

      • 将Pandas 对象存储为json格式
      • path_or_buf=None:文件地址
      • orient:存储的json形式,{‘split’,’records’,’index’,’columns’,’values’}
      • lines:一个对象存储为一行
    3. 案例
      # orient指定存储的json格式,lines指定按照行去变成一个样本
      json_data = pd.read_json(path_or_buf="./data/Sarcasm_Headlines_Dataset.json", orient="records", lines=True)
      json_data.head()
      # 存储文件
      json_data.to_json("./data/test.json", orient='records', lines=True)
      # 读取文件
      new_json = pd.read_json(path_or_buf="./data/test.json", orient="records", lines=True)
      new_json.head()
      
5. DataFrame基本操作与运算
  1. 索引操作

    Numpy当中我们已经讲过使用索引选取序列和切片选择,pandas也支持类似的操作,也可以直接使用列名、行名

    称,甚至组合使用。

    1. 直接索引,必须先列后行

      # # 直接使用行列索引名字的方式(必须先列后行)
      data['open']['2018-02-27']
      
    2. 结合loc(索引)或者iloc(索引的下标)使用索引

      # 使用loc:只能指定行列索引的名字
      data.loc['2018-02-27':'2018-02-22', 'open']
      # 使用iloc可以通过索引的下标去获取
      # 获取前3天数据,前5列的结果
      data.iloc[:3, :5]
      
    3. 使用ix组合索引

      # 使用ix进行下表和名称组合做引
      # 前4天的'open', 'close', 'high', 'low'列数据
      data.ix[0:4, ['open', 'close', 'high', 'low']]
      
      # 推荐使用loc和iloc来获取的方式
      data.loc[data.index[0:4], ['open', 'close', 'high', 'low']]
      data.iloc[0:4, data.columns.get_indexer(['open', 'close', 'high', 'low'])]
      
  2. 赋值操作
    # 对DataFrame当中的close列进行重新赋值为1
    # 直接修改原来的值
    data['close'] = 1
    # 或者
    data.close = 1
    
  3. 排序

    排序有两种形式,一种对于索引进行排序,一种对于内容进行排序

    • DataFrame排序
      • 使用df.sort_values(by=, ascending=),单个键或者多个键进行排序,
      # 按照开盘价大小进行排序 , 使用ascending指定按照大小排序
      data.sort_values(by="open", ascending=True).head()
      # 按照多个键进行排序
      data.sort_values(by=['open', 'high'])
      # 参数:
      # - by:指定排序参考的键
      # - ascending:默认升序
      #  - ascending=False:降序
      #  - ascending=True:升序
      
      
      • 使用df.sort_index给索引进行排序
      # 对索引进行排序
      data.sort_index()
      
    • Series排序
      • 使用series.sort_values(ascending=True)进行排序
      # series排序时,只有一列,不需要参数
      data['p_change'].sort_values(ascending=True).head()
      
      • 使用series.sort_index()进行排序
      # 对索引进行排序
      data['p_change'].sort_index().head()
      
  4. 算术运算
    # 语法:add(other) 加法
    data["open"].add(1)
    # 语法:sub(other) 减法
    data["open"].sub(1)
    
  5. 逻辑运算
    • 逻辑运算符号
      # 逻辑判断的结果可以作为筛选的依据
      data["open"].head() > 23
      data[data["open"] > 23].head()
      # 完成多个逻辑判断
      data[(data["open"] > 23) & (data["open"] < 24)].head()
      
    • 逻辑运算函数
      # 语法:query(expr),expr:查询字符串
      data.query("open<24 & open>23").head()
      # 语法:isin(values),可以指定值进行一个判断,从而进行筛选操作
      # 判断'open'是否为23.53和23.85
      data[data["open"].isin([23.53, 23.85])]
      
  6. 统计运算
    • describe: 能够直接得出很多统计结果,count, mean, std, min, max
      # 计算平均值、标准差、最大值、最小值等
      # 语法:data.describe()
      

      结果: Pandas学习_第2张图片

    • 统计函数

      Numpy当中已经详细介绍,在这里我们演示min(最小值), max(最大值), mean(平均值), median(中位数), var(方差), std(标准差),mode(众数)结果:

      count Number of non-NA observations
      sum Sum of values
      mean Mean of values 平均值
      median Arithmetic median of values 中位数
      min Minimum
      max Maximum
      mode Mode
      abs Absolute Value
      prod Product of values
      std Bessel-corrected sample standard deviation
      var Unbiased variance
      idxmax compute the index labels with the maximum
      idxmin compute the index labels with the minimum

      对于单个函数去进行统计的时候,坐标轴还是按照默认列“columns” (axis=0, default),如果要对行“index” 需要指定(axis=1)

      举例:

      # 使用统计函数:0 代表列求结果, 1 代表行求统计结果, data.max(1)
      data.max() # data.max(0)
      

      Pandas学习_第3张图片

      # 方差:std(),标准差:var()
      data.std(0)
      data.var(0)
      # 中位数 median(),中位数为将数据从小到大排列,在最中间的那个数为中位数。如果没有中间数,取中间两个数的平均值。
      df = pd.DataFrame({'COL1' : [2,3,4,5,4,2],
                         'COL2' : [0,1,2,3,4,2]})
      df.median()
      # 结果
      # COL1    3.5
      # COL2    2.0
      # dtype: float64
      # 求最大值最小值的位置:idxmax()、idxmin()
      data.idxmax(axis=0)
      data.idxmin(axis=0)
      
    • 累计统计函数
      函数 作用
      cumsum 计算前1/2/3/…/n个数的和
      cummax 计算前1/2/3/…/n个数的最大值
      cummin 计算前1/2/3/…/n个数的最小值
      cumprod 计算前1/2/3/…/n个数的积

      以上这些函数可以对series和dataframe操作

      这里我们按照时间的从前往后来进行累计

      # 排序
      data = data.sort_index()
      # 对p_change进行求和
      stock_rise = data["p_change"]
      # plot方法集成了前面直方图、条形图、饼图、折线图
      stock_rise.cumsum()
      
      import matplotlib.pyplot as plt
      # plot显示图形
      stock_rise.cumsum().plot()
      # 需要调用show,才能显示出结果
      plt.show()
      

      结果:
      Pandas学习_第4张图片

  7. 自定义运算
    • apply(func, axis=0)
      • func:自定义函数
      • axis=0:默认是列,axis=1为行进行运算
    • 定义一个对列,最大值-最小值的函数
    data[['open', 'close']].apply(lambda x: x.max() - x.min(), axis=0)
    
6. Panda小案例
  • 需求

    现在我们有一组从2006年到2016年1000部最流行的电影数据

    数据来源:https://www.kaggle.com/damianpanek/sunday-eda/data

    wis = pd.read_csv("https://www.kaggle.com/damianpanek/sunday-eda/data")
    
    • 问题1:我们想知道这些电影数据中评分的平均分,导演的人数等信息,我们应该怎么获取?
    • 问题2:对于这一组电影数据,如果我们想rating,runtime的分布情况,应该如何呈现数据?
    • 问题3:对于这一组电影数据,如果我们希望统计电影分类(genre)的情况,应该如何处理数据?
  • 实现

    首先获取导入包,获取数据
    #内嵌画图
    %matplotlib inline
    import pandas  as pd 
    import numpy as np
    from matplotlib import pyplot as plt
    
    #文件的路径
    path = "./data/IMDB-Movie-Data.csv"
    #读取文件
    df = pd.read_csv(path)
    
  • 问题一
    • 得出评分的平均分

      df["Rating"].mean()
      
    • 得出导演人数信息

      ## 导演的人数
      # df["Director"].unique().shape[0]
      np.unique(df["Director"]).shape[0]
      
  • 问题二

    对于这一组电影数据,如果我们想Rating,Runtime (Minutes)的分布情况,应该如何呈现数据?

    • 直接呈现,以直方图的形式

      df["Rating"].plot(kind='hist',figsize=(20,8))
      
    • Rating进行分布展示

      plt.figure(figsize=(20,8),dpi=80)
      plt.hist(df["Rating"].values,bins=20)
      # 求出最大最小值
      max_ = df["Rating"].max()
      min_ = df["Rating"].min()
      # 生成刻度列表
      t1 = np.linspace(min_,max_,num=21)
      # [ 1.9    2.255  2.61   2.965  3.32   3.675  4.03   4.385  4.74   5.095  5.45   5.805  6.16   6.515  6.87   7.225  7.58   7.935  8.29   8.645  9.   ]
      # 修改刻度
      plt.xticks(t1)
      # 添加网格
      plt.grid()
      plt.show()
      
    • Runtime (Minutes)进行分布展示

      plt.figure(figsize=(20,8),dpi=80)
      plt.hist(df["Runtime (Minutes)"].values,bins=20)
      # 求出最大最小值
      max_ = df["Runtime (Minutes)"].max()
      min_ = df["Runtime (Minutes)"].min()
      # 生成刻度列表
      t1 = np.linspace(min_,max_,num=21)
      # [ 1.9    2.255  2.61   2.965  3.32   3.675  4.03   4.385  4.74   5.095  5.45   5.805  6.16   6.515  6.87   7.225  7.58   7.935  8.29   8.645  9.   ]
      # 修改刻度
      plt.xticks(t1)
      # 添加网格
      plt.grid()
      plt.show()
      
  • 问题三

    对于这一组电影数据,如果我们希望统计电影分类(genre)的情况,应该如何处理数据?

    • 思路分析

      • 思路
        • 1.创建一个全为0的dataframe,列索引置为电影的分类,temp_df
        • 2.遍历每一部电影,temp_df中把分类出现的列的值置为1
        • 3.求和
    • 实现

      # 1.创建一个全为0的dataframe,列索引置为电影的分类
      temp_list = [i.split(",") for i in df["Genre"]]
      # 获取电影的分类(去重)
      genre_list = np.unique([i for j in temp_list for i in j]) 
      # 增加新的列
      temp_df = pd.DataFrame(np.zeros([df.shape[0],genre_list.shape[0]]),columns=genre_list)
      # 2.遍历每一部电影,temp_df中把分类出现的列的值置为1
      for i in range(1000):
          # temp_list[i] ['Action','Adventure','Animation']
          temp_df.ix[i,temp_list[i]]=1
      # 求和 sum(),默认按列“columns”axis=0
      print(temp_df.sum().sort_values())
      temp_df.sum().sort_values().plot(kind="bar")
      

      Pandas学习_第5张图片

你可能感兴趣的:(人工智能,Pandas介绍,Pandas数据结构,DataFrame)