文章目录


机器学习库 - Matplotlib+Numpy+Pandas

1 Matplotlib 基本使用

官方文档:https://matplotlib.org/stable/api/index.html#modules

1.1 特性

  • 强大的数据可视化工具和作图库,是主要用于绘制数据图表的 Python 库,提供了绘制各类可视化图形的命令字库、简单的接口,可以方便用户轻松掌握图形的格式,绘制各类可视化图形。
  • 基于 Numpy 的一套 Python 包,这个包提供了吩咐的数据绘图工具,主要用于绘制一些统计图形。
  • 有一套允许定制各种属性的默认设置,可以控制 Matplotlib 中的每一个默认属性:图像大小、每英寸点数、线宽、色彩和样式、子图、坐标轴、网格属性、文字和文字属性。
1.2 用途:能将数据进行可视化,更直观的呈现;使数据更加客观、更具说服力;
1.3 操作指南

1.3.1 图像结构

在这里插入图片描述
1
2
3
4
5
6
7
8
9
10
import matplotlib.pyplot as plt

# 1.创建画布
plt.figure(figsize=(10, 10), dpi=100)

# 2.绘制折线图
plt.plot([1, 2, 3, 4, 5, 6 ,7], [17,17,18,15,11,11,13])

# 3.显示图像
plt.show()

1.3.2 中文设置问题

  • 解决方案一:

下载中文字体(黑体,看准系统版本)

  • 步骤一:下载 simhei 字体(或者其他的支持中文显示的字体也行)

  • 步骤二:安装字体

    • linux 下:拷贝字体到 usr/share/fonts 下:

      1
      sudo cp ~/SimHei.ttf /usr/share/fonts/SimHei.ttf
    • windows 和 mac 下:双击安装

  • 步骤三:删除~/.matplotlib 中的缓存文件

    1
    2
    cd ~/.matplotlib
    rm -r *
  • 步骤四:修改配置文件 matplotlibrc

    1
    vi ~/.matplotlib/matplotlibrc

    将文件内容修改为:

    1
    2
    3
    font.family         : sans-serif
    font.sans-serif : SimHei
    axes.unicode_minus : False
  • 解决方案二:

      在Python脚本中动态设置matplotlibrc,这样也可以避免由于更改配置文件而造成的麻烦,具体代码如下:
    
    1
    2
    3
    from pylab import mpl
    # 设置显示中文字体
    mpl.rcParams["font.sans-serif"] = ["SimHei"]

    有时候,字体更改后,会导致坐标轴中的部分字符无法正常显示,此时需要更改 axes.unicode_minus 参数:

    1
    2
    # 设置正常显示符号
    mpl.rcParams["axes.unicode_minus"] = False

1.3.3 图像绘制

  • plt.plot(x, y, color='r', linestyle='--')
在这里插入图片描述
  • 刻度显示

    • plt.xticks(刻度值,标签值)

    • plt.yticks(刻度值,标签值)

      注意:在传递进去的第一个参数必须是数字,不能是字符串,如果是字符串,需要进行替换操作

  • 添加网格显示

    • plt.grid(True, linestyle="--", alpha=0.5)
  • 设置标题

    • plt.title('标题',fontsize=20, pad=20)
  • 设置轴标签

    • plt.xlabel()
    • plt.ylabel()
  • 设置轴取值范围

    • plt.xlim(a, b)
    • plt.ylim(a, b)
  • 图像保存

    • plt.savefig("路径")

      注意:plt.show () 会释放 figure 资源,如果在显示图像之后保存图片将只能保存空图片。

  • 显示图例

    • plt.legend(loc="best")
在这里插入图片描述
  • 多个坐标系显示

    • plt.subplots(nrows=, ncols=, figsize=(20, 8), dpi=100)

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      26
      27
      28
      29
      30
      31
      # 1.创建画布
      fig, axes = plt.subplots(nrows=1, ncols=2, figsize=(20, 8), dpi=100)

      # 2.绘制图像
      axes[1].plot(x, y_beijing, color="r", linestyle="--", label="北京")

      # 2.1 添加x,y轴刻度
      x_ticks_label = ["11点{}分".format(i) for i in x]
      y_ticks = range(40)

      # 刻度显示
      axes[1].set_xticks(x[::5])
      axes[1].set_yticks(y_ticks[::5])
      axes[1].set_xticklabels(x_ticks_label[::5])

      # 2.2 添加网格显示
      axes[1].grid(True, linestyle="--", alpha=0.5)

      # 2.3 添加描述信息
      axes[1].set_xlabel("时间")
      axes[1].set_ylabel("温度")
      axes[1].set_title("中午11点--12点某城市温度变化图", fontsize=20)

      # 2.4 图像保存
      plt.savefig("./test.png")

      # 2.5 添加图例
      axes[1].legend(loc=0)

      # 3.图像显示
      plt.show()
1.4 常见图形绘制
  • 1 折线图

    • 定义:以折线的上升或下降来表示统计数量的增减变化的统计图
    • 特点:能够显示数据的变化趋势,反映事物的变化情况。(变化)
    • API: plt.plot(x, y)
  • 2 散点图

    • 定义:用两组数据构成多个坐标点,考察坐标点的分布,判断两变量之间是否存在某种关联或总结坐标点的分布模式。

    • 特点:判断变量之间是否存在数量关联趋势,展示离群点 (分布规律)

    • API: plt.scatter(x, y)

    • 代码实现

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      # 0.准备数据
      x = [225.98, 247.07, 253.14, 457.85, 241.58, 301.01, 20.67, 288.64,
      163.56, 120.06, 207.83, 342.75, 147.9 , 53.06, 224.72, 29.51,
      21.61, 483.21, 245.25, 399.25, 343.35]
      y = [196.63, 203.88, 210.75, 372.74, 202.41, 247.61, 24.9 , 239.34,
      140.32, 104.15, 176.84, 288.23, 128.79, 49.64, 191.74, 33.1 ,
      30.74, 400.02, 205.35, 330.64, 283.45]

      # 1.创建画布
      plt.figure(figsize=(20, 8), dpi=100)

      # 2.绘制散点图
      plt.scatter(x, y)

      # 3.显示图像
      plt.show()
  • 3 柱状图

    • 定义:排列在工作表的列或行中的数据可以绘制到柱状图中。

    • 特点:绘制连离散的数据,能够一眼看出各个数据的大小,比较数据之间的差别。(统计 / 对比)

    • API: plt.bar(x, width, align='center', color= 'r')

      1
      2
      align : 每个柱状图的位置对齐方式
      {‘center’, ‘edge’} 默认: ‘center’
    • 代码实现

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      # 0.准备数据
      # 电影名字
      movie_name = ['雷神3:诸神黄昏','正义联盟','东方快车谋杀案','寻梦环游记','全球风暴','降魔传','追捕','七十七天','密战','狂兽','其它']
      # 横坐标
      x = range(len(movie_name))
      # 票房数据
      y = [73853,57767,22354,15969,14839,8725,8716,8318,7916,6764,52222]

      # 1.创建画布
      plt.figure(figsize=(20, 8), dpi=100)

      # 2.绘制柱状图
      plt.bar(x, y, width=0.5, color=['b','r','g','y','c','m','y','k','c','g','b'])

      # 2.1b修改x轴的刻度显示
      plt.xticks(x, movie_name)

      # 2.2 添加网格显示
      plt.grid(linestyle="--", alpha=0.5)

      # 2.3 添加标题
      plt.title("电影票房收入对比")

      # 3.显示图像
      plt.show()
  • 4 直方图

    • 定义:由一系列高度不等的纵向条纹或线段表示数据分布的情况。 一般用横轴表示数据范围,纵轴表示分布情况。

    • 特点:绘制连续性的数据展示一组或者多组数据的分布状况 (统计)

    • API: plt.hist(x, bins=None)

      1
      bins : 组距
  • 5 饼图

    • 定义:用于表示不同分类的占比情况,通过弧度大小来对比各种分类。

    • 特点:分类数据的占比情况 (占比)

    • API: plt.pie(x, labels=,autopct=,colors)

      1
      2
      3
      4
      x:数量,自动算百分比
      labels:每部分名称
      autopct:占比显示指定%1.2f%%
      colors:每部分颜色
1.5 代码实现
  • 一个坐标系中绘制多个图像

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    import matplotlib.pyplot as plt
    import random
    # from pylab import mpl

    ## 设置显示中文字体
    # mpl.rcParams["font.sans-serif"] = ["SimHei"]
    ## 设置正常显示符号
    # mpl.rcParams["axes.unicode_minus"] = False

    # 0.准备数据
    x = range(60)
    y_shanghai = [random.uniform(15, 18) for i in x]
    y_beijing = [random.uniform(1,3) for i in x]

    # 1.创建画布
    plt.figure(figsize=(20, 8), dpi=100)

    # 2.绘制图像
    plt.plot(x, y_shanghai, label="上海")
    plt.plot(x, y_beijing, color="r", linestyle="--", label="北京")

    # 2.1 添加x,y轴刻度
    # 构造x,y轴刻度标签
    x_ticks_label = ["11点{}分".format(i) for i in x]
    y_ticks = range(40)

    # 刻度显示
    plt.xticks(x[::5], x_ticks_label[::5])
    plt.yticks(y_ticks[::5])

    # 2.2 添加网格显示
    plt.grid(True, linestyle="--", alpha=0.5)

    # 2.3 添加描述信息
    plt.xlabel("时间")
    plt.ylabel("温度")
    plt.title("中午11点--12点某城市温度变化图", fontsize=20)

    # 2.4 图像保存
    plt.savefig("./test.png")

    # 2.5 添加图例
    plt.legend(loc=0)


    # 3.图像显示
    plt.show()
  • 多个坐标系显示 — plt.subplots (面向对象的画图方法)

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    import matplotlib.pyplot as plt
    import random

    # 0.准备数据
    x = range(60)
    y_shanghai = [random.uniform(15, 18) for i in x]
    y_beijing = [random.uniform(1, 5) for i in x]

    # 1.创建画布
    # plt.figure(figsize=(20, 8), dpi=100)
    fig, axes = plt.subplots(nrows=1, ncols=2, figsize=(20, 8), dpi=100)


    # 2.绘制图像
    # plt.plot(x, y_shanghai, label="上海")
    # plt.plot(x, y_beijing, color="r", linestyle="--", label="北京")
    axes[0].plot(x, y_shanghai, label="上海")
    axes[1].plot(x, y_beijing, color="r", linestyle="--", label="北京")

    # 2.1 添加x,y轴刻度
    # 构造x,y轴刻度标签
    x_ticks_label = ["11点{}分".format(i) for i in x]
    y_ticks = range(40)

    # 刻度显示
    # plt.xticks(x[::5], x_ticks_label[::5])
    # plt.yticks(y_ticks[::5])
    axes[0].set_xticks(x[::5])
    axes[0].set_yticks(y_ticks[::5])
    axes[0].set_xticklabels(x_ticks_label[::5])
    axes[1].set_xticks(x[::5])
    axes[1].set_yticks(y_ticks[::5])
    axes[1].set_xticklabels(x_ticks_label[::5])

    # 2.2 添加网格显示
    # plt.grid(True, linestyle="--", alpha=0.5)
    axes[0].grid(True, linestyle="--", alpha=0.5)
    axes[1].grid(True, linestyle="--", alpha=0.5)

    # 2.3 添加描述信息
    # plt.xlabel("时间")
    # plt.ylabel("温度")
    # plt.title("中午11点--12点某城市温度变化图", fontsize=20)
    axes[0].set_xlabel("时间")
    axes[0].set_ylabel("温度")
    axes[0].set_title("中午11点--12点某城市温度变化图", fontsize=20)
    axes[1].set_xlabel("时间")
    axes[1].set_ylabel("温度")
    axes[1].set_title("中午11点--12点某城市温度变化图", fontsize=20)

    # # 2.4 图像保存
    plt.savefig("./test.png")

    # # 2.5 添加图例
    # plt.legend(loc=0)
    axes[0].legend(loc=0)
    axes[1].legend(loc=0)

    # 3.图像显示
    plt.show()

2 Numpy 基本使用

官方文档:https://numpy.org/doc/stable/reference/index.html

2.1 定义

源的 Python 科学计算库,用于快速处理任意维度的数组。

2.2 特点
  • 支持常见的数组和矩阵操作

  • 使用 ndarray 对象来处理多维数组

  • Numpy 比 Python List 区别:

    • Python List 是一个异构(不同类型的数据)的容器
    • Numpy 存储的数据是同质的,类型需相同。
  • Numpy 比 Python List 效率高:

    • 释放GIL :GIL 限制了 Python 线程的并行能力,但 Numpy 不存在此问题。
    • C语言实现
    • 并行计算 :numpy 内置了并行运算功能,当系统有多个核心时,做某种计算时,numpy 会自动做并行计算
    • 内存结构
  • ndarray

    • 属性:反映了数组本身固有的信息

      属性名字 属性解释
      ndarray.shape 数组维度的元组 (行,列,维度)
      ndarray.ndim 数组维数
      ndarray.size 数组中的元素数量
      ndarray.itemsize 一个数组元素的长度(字节)
      ndarray.dtype 数组元素的类型
      1
      2
      3
      4
      # Numpy的常量
      np.Inf 表示无穷大
      np.nan 表示非数字
      np.pi
    • 形状

      1
      2
      3
      4
      5
      6
      7
      8
      # 创建不同形状的数组
      >>> a = np.array([[1,2,3],[4,5,6]])
      >>> b = np.array([1,2,3,4])
      >>> c = np.array([[[1,2,3],[4,5,6]],[[1,2,3],[4,5,6]]])

      >>> a.shape
      >>> b.shape
      >>> c.shape
    • 类型

      1
      2
      3
      # dtype是numpy.dtype类型
      >>> type(score.dtype)
      <type 'numpy.dtype'>
      名称 描述 简写
      np.bool 用一个字节存储的布尔类型(True 或 False) ‘b’
      np.int8 一个字节大小,-128 至 127 ‘i’
      np.int16 整数,-32768 至 32767 ‘i2’
      np.int32 整数,-2^31 至 2^32 -1 ‘i4’
      np.int64 整数,-2^63 至 2^63 - 1 ‘i8’
      np.uint8 无符号整数,0 至 255 ‘u’
      np.uint16 无符号整数,0 至 65535 ‘u2’
      np.uint32 无符号整数,0 至 2^32 - 1 ‘u4’
      np.uint64 无符号整数,0 至 2^64 - 1 ‘u8’
      np.float16 半精度浮点数:16 位,正负号 1 位,指数 5 位,精度 10 位 ‘f2’
      np.float32 单精度浮点数:32 位,正负号 1 位,指数 8 位,精度 23 位 ‘f4’
      np.float64 双精度浮点数:64 位,正负号 1 位,指数 11 位,精度 52 位 ‘f8’
      np.complex64 复数,分别用两个 32 位浮点数表示实部和虚部 ‘c8’
      np.complex128 复数,分别用两个 64 位浮点数表示实部和虚部 ‘c16’
      np.object_ python 对象 ‘O’
      np.string_ 字符串 ‘S’
      np.unicode_ unicode 类型 ‘U’

      注意:若不指定,整数默认 int64,小数默认 float64

2.3 代码实现

1
2
3
4
5
6
7
>>> a = np.array([[1, 2, 3],[4, 5, 6]], dtype=np.float32)
>>> a.dtype
dtype('float32')

>>> arr = np.array(['python', 'tensorflow', 'scikit-learn', 'numpy'], dtype = np.string_)
>>> arr
array([b'python', b'tensorflow', b'scikit-learn', b'numpy'], dtype='|S12')

’|S12’ 介绍

‘|’ 表示字节顺序(不考虑顺序,< (小端))

‘S’ 表示字符串类型

‘12’ 表示数组中每个值最多包含 12 个字节或字符

2.3.1 生成 0 和 1 的数组
  • np.ones(shape, dtype) 创建全是 1 的数组

  • np.ones_like(a, dtype) 根据其它数列形状创建全是 1 的数组

  • np.zeros(shape, dtype) 创建全是 0 的数组

  • np.zeros_like(a, dtype) 根据其它数列形状创建全是 0 的数组

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    # np.ones()
    >>>ones = np.ones([4,8])
    ones

    # np.ones_like()
    >>> x = np.arange(6)
    >>> x = x.reshape((2, 3))
    >>> x
    array([[0, 1, 2],
    [3, 4, 5]])
    >>> np.ones_like(x)
    array([[1, 1, 1],
    [1, 1, 1]])
2.3.2 拷贝
  • np.array(object, dtype) 深拷贝

  • np.asarray(a, dtype) 浅拷贝

    1
    2
    3
    4
    5
    a = np.array([[1,2,3],[4,5,6]])
    # 从现有的数组当中创建
    a1 = np.array(a)
    # 相当于索引的形式,并没有真正的创建一个新的
    a2 = np.asarray(a)
2.3.3 生成固定范围的数组
  • np.linspace (start, stop, num, endpoint) 等差数列

    num : 要生成的等间隔样例数量,默认为 50

    endpoint : 序列中是否包含 stop 值,默认为 ture

  • np.arange(start,stop, step, dtype) 等差数列

    step : 步长,默认值为 1

  • np.logspace(start,stop, num, [base]) 等比数列

    start :float 类型,基底 base 的 start 次幂作为左边界

    stop :float 类型,基底 base 的 stop 次幂作为右边界

    num : 要生成的等比数列数量,默认为 50

    base :float 类型,选填,基底,默认 10

2.3.4 生成随机数

正态分布是一种概率分布。正态分布是具有两个参数 μ 和 σ 的连续型随机变量的分布,第一参数 μ 是服从正态分布的随机变量的均值,第二个参数 σ 是此随机变量的标准差,所以正态分布记作 N(μ,σ )

  • np.random 模块

    • 正态分布
      • np.random.randn(d0, d1, …, dn)

        功能:从标准正态分布中返回一个或多个样本值

      • np.random.normal(loc=0.0, scale=1.0, size=None)

      • np.random.standard_normal(size=None)

        功能:返回指定形状的标准正态分布的数组。

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      import numpy as np

      #randn(d0, d1, ..., dn)
      #standard_normal(size=None)
      #normal(loc=0.0, scale=1.0, size=None)
      a=np.random.randn(3,2) #三行两列的二维数组
      b=np.random.standard_normal(size=[3,2]) #三行两列的二维数组
      c=np.random.normal(2,3,size=[3,2]) #均值为2,标准差为3的三行两列的二维数组

      print(a)
      print('------')
      print(b)
      print('------')
      print(c)
    • 均匀分布
      • np.random.rand(d0, d1, *...*, dn)

        功能:返回 **[0.0,1.0)** 内的一组均匀分布的数。

        1
        2
        3
        >>>np.random.rand(2,4)
        array([[0.45203892, 0.52319708, 0.50009652, 0.34814468],
        [0.49214062, 0.77874009, 0.96667426, 0.94950402]])
      • np.random.uniform(low=0.0, high=1.0, size=None)

        功能:从一个均匀分布 [low,high) 中随机采样,注意定义域是左闭右开,即包含 low,不包含 high.

        low: 采样下界,float 类型,默认值为 0;

        high: 采样上界,float 类型,默认值为 1;

        size: 输出样本数目,为 int 或元组 (tuple) 类型,例如,size=(m,n,k), 则输出 mnk 个样本,缺省时输出 1 个值。

        1
        2
        3
        4
        5
        6
        7
        8
        >>>np.random.uniform(1, 4, size = (2,3,4))
        array([[[3.55647219, 1.6756231 , 3.60677788, 2.3745676 ],
        [3.20914052, 1.63670762, 3.68718528, 1.25277517],
        [3.43555004, 3.76016213, 1.87874796, 2.41035426]],

        [[3.10438403, 3.35162098, 3.42743771, 3.25322821],
        [3.48925817, 2.5992673 , 2.89616745, 3.72254566],
        [3.00571278, 3.66503032, 3.9064071 , 2.84347013]]])
      • np.random.randint(low, high=None, size=None, dtype='l')

        功能:从一个均匀分布中随机采样,生成一个整数或 N 维整数数组。

        • 取数范围:若 high 不为 None 时,取 [low,high) 之间随机整数,否则取值 [0,low) 之间随机整数。
        1
        2
        3
        4
        5
        6
        7
        8
        >>>np.random.randint(1, 4, size = (2,3,4))
        array([[[1, 1, 1, 3],
        [1, 1, 2, 3],
        [1, 2, 1, 2]],

        [[2, 2, 3, 3],
        [2, 1, 2, 2],
        [2, 2, 3, 2]]])
    • 随机整数数组
      • np.random.randint(low, high=None, size=None, dtype=int)
      1
      2
      3
      4
      5
      6
      a = np.random.randint(3)
      b = np.random.randint(4,size=6)
      c = np.random.randint(2,size=(2,3))
      print(a)
      print(b)
      print(c)
2.3.5 数组的索引、切片
  • 切片赋值
    1
    2
    3
    4
    5
    6
    7
    8
    hexo n "博客的文件名">>> import numpy as np
    >>> arr=np.arange(10)
    >>> arr_slice=arr[5:8]
    >>> arr_slice[0]=-1
    >>> arr_slice
    array([-1, 6, 7])
    >>> arr
    array([ 0, 1, 2, 3, 4, -1, 6, 7, 8, 9])
  • 给数组所有元素赋值
    1
    2
    3
    >>> arr[:]=-1
    >>> arr
    array([-1, -1, -1, -1, -1, -1, -1, -1, -1, -1])
  • 使用 copy 方法复制
    1
    2
    3
    4
    5
    6
    7
    8
    >>> arr_copy=arr[:].copy()
    >>> arr_copy
    array([-1, -1, -1, -1, -1, -1, -1, -1, -1, -1])
    >>> arr_copy[:]=0
    >>> arr_copy
    array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0])
    >>> arr
    array([-1, -1, -1, -1, -1, -1, -1, -1, -1, -1])
  • 高阶数组索引
    1
    2
    3
    4
    5
    6
    7
    8
    >>> import numpy as np
    >>> arr2d=np.array([[1,2,3],[4,5,6],[7,8,9]])
    >>> arr2d[2]
    array([7, 8, 9])
    >>> arr2d[0][2]
    3
    >>> arr2d[0,2]
    3
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    >>> import numpy as np
    >>> arr3d=np.array([[[1,2,3],[4,5,6]],[[7,8,9],[10,11,12]]])
    >>> arr3d
    array([[[ 1, 2, 3],
    [ 4, 5, 6]],

    [[ 7, 8, 9],
    [10, 11, 12]]])
    >>> arr3d[0]
    array([[1, 2, 3],
    [4, 5, 6]])
    >>> old_values=arr3d[0].copy()
    >>> arr3d[0]=42
    >>> arr3d
    array([[[42, 42, 42],
    [42, 42, 42]],

    [[ 7, 8, 9],
    [10, 11, 12]]])
    >>> arr3d[1,0]
    array([7, 8, 9])
    >>> x=arr3d[1]
    >>> x
    array([[ 7, 8, 9],
    [10, 11, 12]])
    >>> x[0]
    array([7, 8, 9])
  • 高维数组切片
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    >>> arr2d=np.array([[1,2,3],[4,5,6],[7,8,9]])
    >>> arr2d[:2]
    array([[1, 2, 3],
    [4, 5, 6]])
    >>> arr2d[:2,1:]
    array([[2, 3],
    [5, 6]])
    >>> arr2d[1,:2]
    array([4, 5])
    >>> arr2d[:2,2]
    array([3, 6])
    >>> arr2d[:,:1]
    array([[1],
    [4],
    [7]])
  • 布尔型索引
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    >>> import numpy as np
    >>> names = np.array(['Bob', 'Joe', 'Will', 'Bob', 'Will', 'Joe', 'Joe'])
    >>> data=np.random.randn(7,4)#7行4列正太分布随机数组
    >>> names
    array(['Bob', 'Joe', 'Will', 'Bob', 'Will', 'Joe', 'Joe'], dtype='<U4')
    >>> data
    array([[ 0.24724057, 2.86939948, -0.82061782, -0.65745818],
    [-0.98602372, -0.69305692, -1.44431904, -0.85490816],
    [-0.73613349, 0.12700976, -1.00588979, 1.10646269],
    [ 1.59110894, 1.68597758, 0.39414277, 2.02308399],
    [-1.05607115, -0.50354292, -0.65820553, -0.77610316],
    [ 1.72237936, -0.07726577, 1.63462647, -0.41943148],
    [ 0.66744687, -1.01756773, -0.59254343, 0.19080575]])

    # 选出对应于名字"Bob"的所有行,对names和字符串"Bob"的比较运算将会产生一个布尔型数组。
    >>> names=='Bob'
    array([ True, False, False, True, False, False, False])

    # 获取等于'Bob'的行
    >>> data[names=='Bob']
    array([[ 0.24724057, 2.86939948, -0.82061782, -0.65745818],
    [ 1.59110894, 1.68597758, 0.39414277, 2.02308399]])

    # 获取不同于'Bob'的行
    >>> data[names!='Bob']
    array([[-0.98602372, -0.69305692, -1.44431904, -0.85490816],
    [-0.73613349, 0.12700976, -1.00588979, 1.10646269],
    [-1.05607115, -0.50354292, -0.65820553, -0.77610316],
    [ 1.72237936, -0.07726577, 1.63462647, -0.41943148],
    [ 0.66744687, -1.01756773, -0.59254343, 0.19080575]])

    # 对布尔索引进行列索引
    >>> data[names=='Bob',2:]
    array([[-0.82061782, -0.65745818],
    [ 0.39414277, 2.02308399]])
    >>> data[names=='Bob',3]
    array([-0.65745818, 2.02308399])

    # 反转条件符
    >>> cond=names=='Will'
    >>> cond
    array([False, False, True, False, True, False, False])
    >>> data[~cond]
    array([[ 0.24724057, 2.86939948, -0.82061782, -0.65745818],
    [-0.98602372, -0.69305692, -1.44431904, -0.85490816],
    [ 1.59110894, 1.68597758, 0.39414277, 2.02308399],
    [ 1.72237936, -0.07726577, 1.63462647, -0.41943148],
    [ 0.66744687, -1.01756773, -0.59254343, 0.19080575]])


    # 布尔条件的运算,连接符还有|、&之类
    >>> mask=(names=='Bob')|(names=='Will')
    >>> mask
    array([ True, False, True, True, True, False, False])
    >>> data[mask]
    array([[ 0.24724057, 2.86939948, -0.82061782, -0.65745818],
    [-0.73613349, 0.12700976, -1.00588979, 1.10646269],
    [ 1.59110894, 1.68597758, 0.39414277, 2.02308399],
    [-1.05607115, -0.50354292, -0.65820553, -0.77610316]])

    # 普通条件选取
    >>> data[data<0]=0
    >>> data
    array([[0.24724057, 2.86939948, 0. , 0. ],
    [0. , 0. , 0. , 0. ],
    [0. , 0.12700976, 0. , 1.10646269],
    [1.59110894, 1.68597758, 0.39414277, 2.02308399],
    [0. , 0. , 0. , 0. ],
    [1.72237936, 0. , 1.63462647, 0. ],
    [0.66744687, 0. , 0. , 0.19080575]])

    # 布尔条件选取
    >>> import numpy as np
    >>> names = np.array(['Bob', 'Joe', 'Will', 'Bob', 'Will', 'Joe', 'Joe'])
    >>> data=np.random.randn(7,4)#7行4列正太分布随机数组
    >>> data
    array([[-1.24077681, -0.48320904, 1.22145611, 0.00666619],
    [-0.65078721, -0.03482355, 1.74232625, 0.2979584 ],
    [-1.51669752, 2.04245014, 0.09453898, -0.85531867],
    [-1.51334497, 0.36947066, -0.87016919, 1.35107873],
    [-1.11285867, -2.20906849, 0.38269412, 1.85375798],
    [ 0.95132554, -1.54193589, 1.98741745, -0.60608077],
    [ 0.78902133, 1.41593836, 0.09430052, -0.25057659]])
    >>> data[names!='Joe']=7
    >>> data
    array([[ 7. , 7. , 7. , 7. ],
    [-0.65078721, -0.03482355, 1.74232625, 0.2979584 ],
    [ 7. , 7. , 7. , 7. ],
    [ 7. , 7. , 7. , 7. ],
    [ 7. , 7. , 7. , 7. ],
    [ 0.95132554, -1.54193589, 1.98741745, -0.60608077],
    [ 0.78902133, 1.41593836, 0.09430052, -0.25057659]])
  • 花式索引
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    # 传入单个索引数组
    >>> import numpy as np
    >>> arr=np.empty((8,4))#创建8行4列内容为随机值的数组
    >>> arr
    array([[2.65577744e-260, 7.70858946e+218, 6.01334668e-154,
    4.47593816e-091],
    [7.01413727e-009, 2.96905203e+222, 2.11672643e+214,
    4.56532297e-085],
    [4.78409596e+180, 2.44001263e-152, 2.45981714e-154,
    6.83528875e+212],
    [6.14829725e-071, 1.05161522e-153, 1.05135742e-153,
    2.43902457e-154],
    [4.83245960e+276, 6.03103052e-154, 7.06652000e-096,
    2.65862875e-260],
    [1.76380220e+241, 2.30576063e-310, 9.80013217e+040,
    1.55850644e-312],
    [1.33360318e+241, 4.09842267e-310, 2.48721655e-075,
    1.04922745e-312],
    [1.91217285e-309, 1.18182126e-125, 6.57144273e-299,
    5.54240979e-302]])
    >>> for i in range(8):
    arr[i]=i

    >>> arr
    array([[0., 0., 0., 0.],
    [1., 1., 1., 1.],
    [2., 2., 2., 2.],
    [3., 3., 3., 3.],
    [4., 4., 4., 4.],
    [5., 5., 5., 5.],
    [6., 6., 6., 6.],
    [7., 7., 7., 7.]])
    >>> arr[[4,3,0,6]]#选特定的索引下标,选取第4,3,0,6行
    array([[4., 4., 4., 4.],
    [3., 3., 3., 3.],
    [0., 0., 0., 0.],
    [6., 6., 6., 6.]])
    >>> arr[[-3,-5,-7]]#选择特定的索引下标,选取第-3,-5,-7行
    array([[5., 5., 5., 5.],
    [3., 3., 3., 3.],
    [1., 1., 1., 1.]])


    # 传入多个索引数组
    >>> arr=np.arange(32).reshape((8,4))
    >>> arr
    array([[ 0, 1, 2, 3],
    [ 4, 5, 6, 7],
    [ 8, 9, 10, 11],
    [12, 13, 14, 15],
    [16, 17, 18, 19],
    [20, 21, 22, 23],
    [24, 25, 26, 27],
    [28, 29, 30, 31]])
    >>> arr[[1,5,7,2],[0,3,1,2]]#选取(1,0),(5,3),(7,1),(2,2)对应元素
    array([ 4, 23, 29, 10])


    >>> arr[[1,5,7,2]][:,[0,3,1,2]]#先选取第1,5,7,2行,再将每行按照0,3,1,2这个顺序交换
    array([[ 4, 7, 5, 6],
    [20, 23, 21, 22],
    [28, 31, 29, 30],
    [ 8, 11, 9, 10]])
2.3.6 形状修改
  • ndarray.reshape(shape, order)

    返回一个具有相同数据域,但 shape 不一样的视图

    行、列不进行互换

    1
    2
    3
    # 在转换形状的时候,一定要注意数组的元素匹配
    stock_change.reshape([5, 4])
    stock_change.reshape([-1,10]) # 数组的形状被修改为: (2, 10), -1: 表示通过待计算
  • ndarray.resize(new_shape)

    修改数组本身的形状(需要保持元素个数前后相同)

    行、列不进行互换

    1
    2
    3
    4
    stock_change.resize([5, 4])
    # 查看修改后结果
    stock_change.shape
    (5, 4)
  • ndarray.T

    数组的转置

    将数组的行、列进行互换

    1
    2
    stock_change.T.shape
    (4, 5)
2.3.7 类型修改
  • ndarray.astype(type)

    返回修改了类型之后的数组

    1
    stock_change.astype(np.int32)
  • ndarray.tobytes([order])

    构造包含数组中原始数据字节的 Python 字节

    1
    2
    arr = np.array([[[1, 2, 3], [4, 5, 6]], [[12, 3, 34], [5, 6, 7]]])
    arr.tobytes()

常见问题:jupyter 输出太大可能导致崩溃问题

1
2
3
4
5
IOPub data rate exceeded.
The notebook server will temporarily stop sending output
to the client in order to avoid crashing it.
To change this limit, set the config variable
`--NotebookApp.iopub_data_rate_limit`.

解决方案

(1)创建配置文件

1
2
jupyter notebook --generate-config
vi ~/.jupyter/jupyter_notebook_config.py

(2)取消注释,修改限制

1
2
3
## (bytes/sec) Maximum rate at which messages can be sent on iopub before they
# are limited.
c.NotebookApp.iopub_data_rate_limit = 10000000
2.3.8 数组去重
  • np.unique()

    1
    2
    3
    temp = np.array([[1, 2, 3, 4],[3, 4, 5, 6]])
    >>> np.unique(temp)
    array([1, 2, 3, 4, 5, 6])
2.3.9 逻辑运算
  • 利用布尔索引进行运算,提取满足布尔条件的值或者给满足条件的值进行赋值等。
2.3.10 通用判断函数
  • np.all()

    1
    2
    3
    # 判断前两名同学的成绩[0:2, :]是否全及格
    >>> np.all(score[0:2, :] > 60)
    False
  • np.any()

    1
    2
    3
    # 判断前两名同学的成绩[0:2, :]是否有大于90分的
    >>> np.any(score[0:2, :] > 80)
    True

2.3.11 三元运算符

  • np.where()

    1
    2
    3
    4
    5
    6
    7
    8
    9
    # 判断前四名学生,前四门课程中,成绩中大于60的置为1,否则为0
    temp = score[:4, :4]

    np.where(temp > 60, 1, 0)
    # 判断前四名学生,前四门课程中,成绩中大于60且小于90的换为1,否则为0
    np.where(np.logical_and(temp > 60, temp < 90), 1, 0)

    # 判断前四名学生,前四门课程中,成绩中大于90或小于60的换为1,否则为0
    np.where(np.logical_or(temp > 90, temp < 60), 1, 0)

2.3.12 统计运算

  • min (a, axis) # 最小值
  • max (a, axis]) # 最大值
  • median (a, axis) # 中位数
  • mean (a, axis, dtype) # 均值
  • std (a, axis, dtype) # 标准差
  • var (a, axis, dtype) # 方差
  • argmin (a, axis) # 对应最小值数据的下标
  • argmin (a, axis) # 对应最大值数据的下标

2.3.13 数组间的运算

  • 广播机制 :数组在进行矢量化运算时,要求数组的形状是相等的。当形状不相等的数组执行算术运算的时候,就会出现广播机制,该机制会对数组进行扩展,使数组的 shape 属性值一样,以进行矢量化运算。

2.3.14 矩阵运算

  • matrix 和 array 区别

    • 矩阵必须是 2维
    • array 可以是 多维
  • 矩阵运算规则

在这里插入图片描述
  • 创建矩阵

    • np.matrix(np.random.randint(0, 10, (2, 5)))

    • np.identity(n) # 创建 n 维单位矩阵

  • 矩阵操作

    • array1 * array2 # 矩阵乘法
    • array ** -1 # 矩阵转置
  • 矩阵 API

    • np.matmul (a,b) #矩阵乘法,禁止矩阵与标量进行计算
    • np.dot (a,b) # 矩阵乘法,可以进行矩阵与标量的计算

3 Pandas 基本使用

官方文档:https://pandas.pydata.org/docs/reference/index.html

3.1 定义

python+data+analysis 的组合缩写 (另一种解释为: pandas = panel + dataframe + series ),是 python 中基于 numpy 和 matplotlib 的第三方数据分析库,与后两者共同构成了 python 数据分析的基础工具包,享有数分三剑客之名。有数据分析界的瑞士军刀之称。

3.2 特点
  • 增强图表可读性

    • 常用的数据分析与统计功能,包括基本统计量、分组统计分析等
  • 便捷的数据处理能力

    • 类比 SQL 的 join 和 groupby 功能,pandas 可以很容易实现 SQL 这两个核心功能,实际上,SQL 的绝大部分 DQL 和 DML 操作在 pandas 中都可以实现
    • 类比 Excel 的数据透视表功能,Excel 中最为强大的数据分析工具之一是数据透视表,这在 pandas 中也可轻松实现
    • 自带正则表达式的字符串向量化操作,对 pandas 中的一列字符串进行通函数操作,而且自带正则表达式的大部分接口
    • 丰富的时间序列向量化处理接口
  • 读取文件方便

    • 按索引匹配的广播机制,这里的广播机制与 numpy 广播机制还有很大不同

    • 便捷的数据读写操作,相比于 numpy 仅支持数字索引,pandas 的两种数据结构均支持标签索引,包括 bool 索引也是支持的

  • 封装了 Matplotlib、Numpy 的画图和计算

    • 集成 matplotlib 的常用可视化接口,无论是 series 还是 dataframe,均支持面向对象的绘图接口
3.3 操作
  • Series :一维数组结构,主要由一组数据和与之相关的索引两部分构成。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    # 导入pandas
    import pandas as pd

    # API结构
    pd.Series(data=None, index=None, dtype=None)

    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})
    • pd.Series.data # 获得数据
  • pd.Series.index # 获得索引

    • pd.Series.value # 获得值
    • pd.Series.dtype # 获得类型
  • DataFrame :二维数组,既有行索引,又有列索引。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    # 导入pandas
    import pandas as pd

    # 行索引,表明不同行,横向索引,叫index,0轴,axis=0
    # 列索引,表名不同列,纵向索引,叫columns,1轴,axis=1
    pd.DataFrame(data=None, index=None, columns=None)

    pd.DataFrame(np.random.randn(2,3))

    pd.DataFrame(np.random.randint(0, 10, (10, 10)))

    # 构造行索引序列
    subjects = ["语文", "数学", "英语", "政治", "体育"]
    # 构造列索引序列
    stu = ['同学' + str(i) for i in range(score_df.shape[0])]
    # 添加行列索引
    data = pd.DataFrame(score, columns=subjects, index=stu)


    • pd.DataFrame.shape # 数组结构
    • pd.DataFrame.index # 数组行索引列表
    • pd.DataFrame.colums # 数组列索引列表
    • pd.DataFrame.values # 数组的值
    • pd.DataFrame.T # 数组转置
    • pd.DataFrame.head (n) # 数组前 n 行,默认 5 行
    • pd.DataFrame.tail (n) # 数组后 n 行,默认 5 行
    • pd.reset_index (drop=False) # 设置新的下标索引,drop 为是否删除原来索引,默认 False。
    • set_index (keys, drop=True) # 以名为 keys 的列表值设置为新索引,drop 默认值为 True。
  • MultiIndex:三维的数据结构

    • 多级索引(层次化索引),可以在 Series、DataFrame 对象上拥有 2 个以及 2 个以上的索引

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      df = pd.DataFrame({'month': [1, 4, 7, 10],
      'year': [2012, 2014, 2013, 2014],
      'sale':[55, 40, 84, 31]})
      # 使用DataFrame构造多索引的MultiIndex结构
      df = df.set_index(['year', 'month'])
      df

      >>>
      sale
      year month
      2012 1 55
      2014 4 40
      2013 7 84
      2014 10 31

      # 打印行索引结果
      df.index

      >>>
      MultiIndex(levels=[[2012, 2013, 2014], [1, 4, 7, 10]],
      labels=[[0, 2, 1, 2], [0, 1, 2, 3]],
      names=['year', 'month'])
    • 代码实现

      1
      2
      3
      4
      5
      6
      7
      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'])
3.4 Numpy 和 Pandas 区别及联系
  • Pandas 是在 Numpy 基础上实现,其核心数据结构与 Numpy 的 ndarray 十分相似,但 Pandas 与 Numpy 的关系不是替代,而是互为补充。二者之间主要区别是:

    • 从数据结构上看:

      • numpy 的核心数据结构是 ndarray ,支持任意维数的数组,但要求单个数组内所有数据是 同质的 ,即类型必须相同;

      • pandas 的核心数据结构是 seriesdataframe ,仅支持一维和二维数据,但数据内部可以是 异构 数据,仅要求同列数据类型一致即可

      • numpy 的数据结构仅支持 数字索引

      • pandas 数据结构则同时支持 数字索引标签索引

    • 从功能定位上看:

      • numpy 虽然也支持字符串等其他数据类型,但仍然主要是用于 数值计算 ,尤其是内部集成了大量矩阵计算模块,例如基本的矩阵运算、线性代数、fft、生成随机数等,支持灵活的广播机制

      • pandas 主要用于 数据处理与分析 ,支持包括数据读写、数值计算、数据处理、数据分析和数据可视化全套流程操作

      Excel 透视表:数据透视表(Pivot Table)是一种交互式的表,可以进行某些计算,如求和与计数等。所进行的计算与数据跟数据透视表中的排列有关。

      之所以称为数据透视表,是因为可以动态地改变它们的版面布置,以便按照不同方式分析数据,也可以重新安排行号、列标和页字段。每一次改变版面布置时,数据透视表会立即按照新的布置重新计算数据。另外,如果原始数据发生更改,则可以更新数据透视表。

3.5 Series 和 Dataframe 区别

Pandas 核心数据结构有两种,即一维的 series 和二维的 dataframe,二者可以分别看做是在 numpy 一维数组和二维数组的基础上增加了相应的标签信息。正因如此,可以从两个角度理解 series 和 dataframe:

  • series 和 dataframe 分别是一维和二维数组,因为是数组,所以 numpy 中关于数组的用法基本可以直接应用到这两个数据结构,包括数据创建、切片访问、通函数、广播机制等
  • series 是带标签的一维数组,所以还可以看做是 类字典 结构:标签是 key,取值是 value;而 dataframe 则可以看做是 嵌套字典 结构,其中列名是 key,每一列的 series 是 value。所以从这个角度讲,pandas 数据创建的一种灵活方式就是通过字典或者嵌套字典,同时也自然衍生出了适用于 series 和 dataframe 的类似字典访问的接口,即通过 loc 索引访问。
3.6 基本数据操作
  • 1 索引

    • 直接索引 – 先列后行,是需要通过索引的字符串进行获取

    • loc – 先行后列,是需要通过索引的字符串进行获取

    • iloc – 先行后列,是通过下标进行索引

    • ix – 先行后列,可以用上面两种方法混合进行索引

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      26
      27
      28
      29
      30
      31
      32
      # 使用loc:只能指定行列索引的名字
      data.loc['2018-02-27':'2018-02-22', 'open']

      >>>
      2018-02-27 23.53
      2018-02-26 22.80
      2018-02-23 22.88
      Name: open, dtype: float64

      # 使用iloc可以通过索引的下标去获取
      # 获取前3天数据,前5列的结果
      data.iloc[:3, :5]

      >>>
      open high close low
      2018-02-27 23.53 25.88 24.16 23.53
      2018-02-26 22.80 23.78 23.53 22.80
      2018-02-23 22.88 23.37 22.82 22.71

      # 使用ix进行下表和名称组合做引
      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'])]

      >>>
      open close high low
      2018-02-27 23.53 24.16 25.88 23.53
      2018-02-26 22.80 23.53 23.78 22.80
      2018-02-23 22.88 22.82 23.37 22.71
      2018-02-22 22.25 22.28 22.76 22.02
  • 2 赋值

    • data["***"] = **
    • data.*** =
  • 3 排序

    • Dataframe

      • 对象.sort_values(by=, ascending=) # ascending 默认为 True,表示升序排列

      • 对象.sort_index() # 对索引进行排序

        1
        2
        3
        4
        5
        6
        7
        8
        # 按照开盘价大小进行排序 , 使用ascending指定按照大小排序
        data.sort_values(by="open", ascending=True).head()

        # 按照多个键进行排序
        data.sort_values(by=['open', 'high'])

        # 对索引进行排序
        data.sort_index()
    • series

      • 对象.sort_values(ascending=True)

      • 对象.sort_index()

        1
        2
        3
        4
        5
        6
        7
        8
        9
        10
        11
        12
        13
        14
        15
        16
        17
        18
        19
        20
        data['p_change'].sort_values(ascending=True).head()

        >>>
        2015-09-01 -10.03
        2015-09-14 -10.02
        2016-01-11 -10.02
        2015-07-15 -10.02
        2015-08-26 -10.01
        Name: p_change, dtype: float64

        # 对索引进行排序
        data['p_change'].sort_index().head()

        >>>
        2015-03-02 2.62
        2015-03-03 1.44
        2015-03-04 1.57
        2015-03-05 2.02
        2015-03-06 8.51
        Name: p_change, dtype: float64
3.7 DataFram 运算
  • 1 算术运算

    • 对象.add() # 求和
    • 对象.sub() # 求差
  • 2 逻辑运算

    • 1. 逻辑运算符号

      1
      2
      # 多个逻辑判断
      data[(data["open"] > 23) & (data["open"] < 24)].head()
    • 2. 逻辑运算函数

      • 对象.query(expr) # 查询字符串 expr

        1
        data.query("open<24 & open>23").head()
      • 对象.isin(values) # 判断对象是否在 values 中

        1
        2
        # 可以指定值进行一个判断,从而进行筛选操作
        data[data["open"].isin([23.53, 23.85])]
  • 3 统计运算

    • 1. 对象.describe () # 综合分析,得出多种统计结果, count , mean , std , min , max

      1
      2
      # 计算平均值、标准差、最大值、最小值
      data.describe()
    • 2. 统计函数

      函数 作用
      count 计数
      sum 求和
      mean 均值
      median 中位数
      min 最小值
      max 最大值
      mode 众数
      abs 绝对值
      prod 所有项乘积
      std 标准差
      var 方差
      idxmax 最大值位置
      idxmin 最小值位置
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      # 求出最小值的位置
      data.idxmin(axis=0)

      >>>
      open 2015-03-02
      high 2015-03-02
      close 2015-09-02
      low 2015-03-02
      volume 2016-07-06
      price_change 2015-06-15
      p_change 2015-09-01
      turnover 2016-07-06
      my_price_change 2015-06-15
      dtype: object
    • 3. 累积统计函数

      函数 作用
      cumsum 计算前 1/2/3/…/n 个数的和
      cummax 计算前 1/2/3/…/n 个数的最大值
      cummin 计算前 1/2/3/…/n 个数的最小值
      cumprod 计算前 1/2/3/…/n 个数的积
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      # 排序之后,进行累计求和
      data = data.sort_index()

      stock_rise = data['p_change']
      # plot方法集成了前面直方图、条形图、饼图、折线图
      stock_rise.cumsum()

      2015-03-02 2.62
      2015-03-03 4.06
      2015-03-04 5.63
      2015-03-05 7.65
      2015-03-06 16.16
      2015-03-09 16.37
      2015-03-10 18.75
      2015-03-11 16.36
      2015-03-12 15.03
      2015-03-13 17.58
      2015-03-16 20.34
      2015-03-17 22.42
  • 4 自定义运算

    • apply(func, axis=0)

      1
      2
      3
      4
      5
      6
      data[['open', 'close']].apply(lambda x: x.max() - x.min(), axis=0)

      >>>
      open 22.74
      close 22.85
      dtype: float64
3.8 Pandas 画图

3.9 文件读取与存储

  • CSV

    • pandas.read_csv(filepath_or_buffer, sep =',', usecols )

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      # 读取文件,并且指定只获取'open', 'close'指标
      # sep :分隔符,默认用","隔开
      # usecols:指定读取的列名,列表形式
      data = pd.read_csv("./data/stock_day.csv", usecols=['open', 'close'])

      open close
      2018-02-27 23.53 24.16
      2018-02-26 22.80 23.53
      2018-02-23 22.88 22.82
      2018-02-22 22.25 22.28
      2018-02-14 21.49 21.92
    • DataFrame.to_csv(path_or_buf=None, sep=', ’, columns=None, header=True, index=True, mode='w', encoding=None)

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

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

      1
      2
      # 读取day_close的数据
      new_close = pd.read_hdf("./data/test.h5", key="day_close")
    • DataFrame.to_hdf(path_or_buf, *key*, **\*kwargs*)

      1
      2
      # 将day_close数据项存储到一个文件
      day_close.to_hdf("./data/test.h5", key="day_close")
  • JSON

    • pandas.read_json(path_or_buf=None, orient=None, typ='frame', lines=False)

      1
      2
      # orient指定存储的json格式,lines指定按照行去变成一个样本
      json_read = pd.read_json("./data/Sarcasm_Headlines_Dataset.json", orient="records", lines=True)
    • DataFrame.to_json(*path_or_buf=None*, *orient=None*, *lines=False*)

      1
      2
      3
      4
      # 将Pandas 对象存储为json格式
      # path_or_buf=None:文件地址
      # orient:存储的json形式,{‘split’,’records’,’index’,’columns’,’values’}
      # lines:一个对象存储为一行
3.10 缺失值处理
  • isnull、notnull 判断是否存在缺失值
    • np.any(pd.isnull(movie)) # 里面如果有一个缺失值,就返回 True
    • np.all(pd.notnull(movie)) # 里面如果有一个缺失值,就返回 False
  • dropna 删除 np.nan 标记的缺失值
    • movie.dropna()
  • fillna 填充缺失值
    • movie[i].fillna(value=movie[i].mean(), inplace=True)
  • replace 替换具体某些值
    • wis.replace(to_replace="?", value=np.NaN)
3.11 数据离散化
  • 数据离散化目的:

    • 可以用来减少给定连续属性值的个数
    • 在连续属性的值域上,将值域划分为若干个离散的区间,最后用不同的符号或整数值代表落在每个子区间中的属性值。
  • 实现 API

    • pd.qcut(data, q)

      对数据进行分组将数据分组,一般会与 value_counts 搭配使用,统计每组的个数

    • series.value_counts() # 统计分组次数

    • pd.cut(data, bins) # 自定义区间分组

  • 独热编码(one-hot 编码

    • 把每个类别生成一个布尔列,这些列中只有一列可以为这个样本取值为

    • pandas.get_dummies(*data*, *prefix=None*)

      1
      2
      # 得出one-hot编码矩阵
      dummies = pd.get_dummies(p_counts, prefix="rise")

3.12 高级处理 - 合并

  • pd.concat ([数据 1, 数据 2], axis=1) # 数据合并

    1
    2
    # 按照行索引进行
    pd.concat([data, dummies], axis=1)
  • pd.merge(left, right, how=‘inner’, on=None)

    • left: DataFrame
    • right: 另一个 DataFrame
    • how – 以何种方式连接
    • on – 连接的键的依据是哪几个
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    left = pd.DataFrame({'key1': ['K0', 'K0', 'K1', 'K2'],
    'key2': ['K0', 'K1', 'K0', 'K1'],
    'A': ['A0', 'A1', 'A2', 'A3'],
    'B': ['B0', 'B1', 'B2', 'B3']})

    right = pd.DataFrame({'key1': ['K0', 'K1', 'K1', 'K2'],
    'key2': ['K0', 'K0', 'K0', 'K0'],
    'C': ['C0', 'C1', 'C2', 'C3'],
    'D': ['D0', 'D1', 'D2', 'D3']})

    # 默认内连接
    result = pd.merge(left, right, on=['key1', 'key2'])

    # 左连接
    result = pd.merge(left, right, how='left', on=['key1', 'key2'])

    # 右连接
    result = pd.merge(left, right, how='right', on=['key1', 'key2'])

    # 外链接
    result = pd.merge(left, right, how='outer', on=['key1', 'key2'])
3.13 高级处理 - 交叉表与透视表
  • 交叉表:

    交叉表用于计算一列数据对于另外一列数据的分组个数 (用于统计分组频率的特殊透视表)

    • pd.crosstab(value1, value2)
  • 透视表:

    透视表是将原有的 DataFrame 的列分别作为行索引和列索引,然后对指定的列应用聚集函数

    • data.pivot_table()

    • DataFrame.pivot_table([], index=[])

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    # 寻找星期几跟股票张得的关系
    # 1、先把对应的日期找到星期几
    date = pd.to_datetime(data.index).weekday
    data['week'] = date

    # 2、假如把p_change按照大小去分个类0为界限
    data['posi_neg'] = np.where(data['p_change'] > 0, 1, 0)

    # 通过交叉表找寻两列数据的关系
    count = pd.crosstab(data['week'], data['posi_neg'])

    # 算数运算,先求和
    sum = count.sum(axis=1).astype(np.float32)

    # 进行相除操作,得出比例
    pro = count.div(sum, axis=0)

    pro.plot(kind='bar', stacked=True)
    plt.show()

    # 通过透视表,将整个过程变成更简单一些
    data.pivot_table(['posi_neg'], index='week')
3.14 高级处理 - 分组与聚合
  • DataFrame.groupby(key, as_index=False)

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    col =pd.DataFrame({'color': ['white','red','green','red','green'], 'object': ['pen','pencil','pencil','ashtray','pen'],'price1':[5.56,4.20,1.30,0.56,2.75],'price2':[4.75,4.12,1.60,0.75,3.15]})

    >>>
    color object price1 price2
    0 white pen 5.56 4.75
    1 red pencil 4.20 4.12
    2 green pencil 1.30 1.60
    3 red ashtray 0.56 0.75
    4 green pen 2.75 3.15

    # 分组,求平均值
    col.groupby(['color'])['price1'].mean()
    col['price1'].groupby(col['color']).mean()

    >>>
    color
    green 2.025
    red 2.380
    white 5.560
    Name: price1, dtype: float64

    # 分组,数据的结构不变
    col.groupby(['color'], as_index=False)['price1'].mean()

    >>>
    color price1
    0 green 2.025
    1 red 2.380
    2 white 5.560
× 请我吃糖~
打赏二维码