大数据 - NumPy

Jupyter

  • 准备工作

    1. 下载并安装 Anaconda3
      • 配置环境变量:在 path 路径下面追加
        1
        2
        1.C:\anaconda3
        2.C:\anaconda3\Scripts
    2. 安装 opencv:pip install opencv-python
    3. 安装 tensorflow
      • 打开 Anaconda Prompt,输入清华仓库镜像,这样更新会快一些:
        1
        conda config --add channels https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/free/
        1
        conda config --set show_channel_urls yes

        不想换源的也可以不换。

      • 在 Anaconda Prompt 中利用 Anaconda 创建一个 python3.7 的环境,环境名称为 tensorflow ,输入下面命令:
        1
        conda create -n tensorflow python=3.7

        运行 开始菜单 ->Anaconda3—>Anaconda Navigator,点击左侧的 Environments,可以看到 tensorflow 的环境已经创建好了。

      • 在 Anaconda Prompt 中启动 tensorflow 环境:
        1
        activate tensorflow

        注:当不使用 tensorflow 时,关闭 tensorflow 环境,命令为:deactivate

      • 安装 cpu 版本的 TensorFlow
        1
        pip install --upgrade --ignore-installed tensorflow
      • 测试 tensorflow:在 Anaconda Prompt 中启动 tensorflow 环境,并进入 python 环境。
        • 测试代码如下:
          1
          2
          3
          import tensorflow as tf
          msg = tf.constant('Hello, TensorFlow!')
          tf.print(msg)
  • 或许到这里我们并没有满足,我们在 Anaconda 自带的 ipython 和 Spyder 中 import tensorflow 的时候一直失败,提示 No module named ‘tensorflow’,那是因为我们没有在 tensorflow 的环境下打开它们。

    • 为了能在 ipython 和 Spyder 中使用 tensorflow,我们需要在 tensorflow 的环境中安装这两个的插件。
      • 打开 Anaconda Navigator,选择 Not installed,找到 ipython 和 Spyder 并安装。(ipython 可能已经自动安装,切换到 installed 可以看到。)
      • 切换到 installed,可以看到两个都已经安装好,其实可以按照自己的需要安装。
      • 安装好插件后,我们需要测试一下:
        • 在 Anaconda Prompt 中启动 tensorflow 环境,并运行 ipython,import tensorflow 发现成功。
        • 同样,在 Anaconda Prompt 中启动 tensorflow 环境,并运行 Spyder,等一会儿后会启动 Spyder IDE,import tensorflow 同样成功。
  • jupyter 简单使用

    • 启动:在 Anaconda Prompt 中启动 base 环境,然后切换到工作目录输入以下命令:

      1
      jupyter notebook

      这个命令可以启动 jupyter 的交互服务器,并且把当前目录作为映射打开一个 web 界面,加载映射的目录结构。

      注意:如果这个命令提示错误,检查环境变量还有 anaconda 是否安装完全(如果安装不完全:手动安装 pip install jupyter

    • 运行程序:4 种方式

      1. 点击 “运行” 按钮
      2. Ctrl + enter:运行当前 cell 并且选中当前 cell
      3. Shift + enter:运行当前 cell 并且选中下一个 cell
      4. Alt + enter:运行当前 cell 并且创建一个新的 cell,且选中新创建的 cell
  • 帮助文档

    • 使用 help()help(len)
    • 使用 ?len?len??
      • 一个?:显示这个函数的帮助文档
      • 两个??:显示帮助文档和源码(如果不开源则不显示)
    • 使用 "tab" 键自动补全
  • 魔法指令

    1. 运行在外部 Python 文件:%run xx.py

      1
      %run hello.py

      当魔法指令运行一个外部文件以后,该文件的函数就可以在 cell 会话中使用

    2. 查看运行计时:

      • %time python语句:查看程序运行的时间

        1
        2
        %time print('hello')
        %time fun1()
      • %timeit statement:用于计算 statement 的平均运行时间 % timeit 会多次运行 statement,最后得到一个比较准确的运行时间

        1
        %timeit fun1()
      • %%timeit可以测试多行代码的平均运行时间 %% timeit statement1 statement2 ...

        1
        2
        3
        %%timeit
        print('xxxxxxxx')
        fun1()
      • %time 一般用于耗时比较长的代码段 %timeit 一般用于耗时比较短的代码段

    3. 查看当前会话中所有的变量与函数:

      • %whos:查看当前会话的所有变量与函数的详细信息
      • %who_ls:以列表形式显示当前会话的所有变量与函数
        1
        2
        %whos
        %who_ls
    4. 执行系统终端指令:写法:! 指令名(在 windows 系统下应该执行 Windows 的系统命令,linux 要执行对应的 Linux 版本的系统指令)

      1
      !ipconfig
    5. 更多魔法指令或者 cmd:列出所有的魔法指令 %lsmagic

      1
      2
      3
      4
      5
      6
      7
      Available line magics:
      %alias %alias_magic %autoawait %autocall %automagic %autosave %bookmark %cd %clear %cls %colors %conda %config %connect_info %copy %ddir %debug %dhist %dirs %doctest_mode %echo %ed %edit %env %gui %hist %history %killbgscripts %ldir %less %load %load_ext %loadpy %logoff %logon %logstart %logstate %logstop %ls %lsmagic %macro %magic %matplotlib %mkdir %more %notebook %page %pastebin %pdb %pdef %pdoc %pfile %pinfo %pinfo2 %pip %popd %pprint %precision %prun %psearch %psource %pushd %pwd %pycat %pylab %qtconsole %quickref %recall %rehashx %reload_ext %ren %rep %rerun %reset %reset_selective %rmdir %run %save %sc %set_env %store %sx %system %tb %time %timeit %unalias %unload_ext %who %who_ls %whos %xdel %xmode

      Available cell magics:
      %%! %%HTML %%SVG %%bash %%capture %%cmd %%debug %%file %%html %%javascript %%js %%latex %%markdown %%perl %%prun %%pypy %%python %%python2 %%python3 %%ruby %%script %%sh %%svg %%sx %%system %%time %%timeit %%writefile

      Automagic is ON, % prefix IS NOT needed for line magics.

      %cd?:显示对应魔法指令的帮助文档

  • 快捷键

    • 命令模式下:

      1
      2
      3
      4
      5
      6
      7
      8
      9
      enter:       转入编辑模式
      shift+enter: 运行本行,并且选中下行
      ctrl+enter: 运行本行,并且选中本行
      alt+enter: 运行本行,并且插入一个新的cell

      Y:cell转入代码状态
      M:cell转入Markdown状态
      A: 在上方插入一个新的cell
      B:在下方插入一个新的cell
    • 编辑模式下:

      1
      2
      3
      tab(shift + tab)键:  提示
      Ctrl + a: 权限当前cell
      Ctrl + z: 撤销

NumPy

  • 什么是 numpy?

    • Numpy 即 Numeric Python,python 经过扩展可以支持数组和矩阵类型,并且具有大量的函数可以计算这些数组和矩阵。这些数组一般是多维的,而这个扩展的程序包就是 numpy。
    • 【注】是数据分析和机器学习中最基本的工具,后面许多 API 和工具都是建立在他得基础上,如:pandas、scipy、matplotlib 等
  • 导入 numpy 并查看版本

    1
    2
    3
    import numpy as np

    np.__version__
  • 创建 ndarray:numpy 中最基础数据结构就是 ndarray:即数组

    1. 使用 np.array()python list 创建

      1
      2
      3
      data = [1,2,3]
      nd = np.array(data)
      nd
      1
      2
      nd2 = np.array([1,2,3,4,True,'1234'])
      nd2
      1
      nd2.dtype # 数组中元素的类型

      注意:数组中所有的元素类型相同;如果通过列表来创建的时候,列表中的元素不一样,会被统一成某种类型(优先级:str>float>int)。

      1
      2
      3
      4
      5
      # 引入一张图片
      import matplotlib.pyplot as plt # 这个是用于处理数据可视化的一个工具

      girl = plt.imread("./source/girl.jpg")
      girl

      注意:图片也可以在 numpy 里面用数组来表示,彩色图片是三维的数组

      1
      girl.shape # 数据形状
      1
      2
      plt.imshow(girl)
      plt.show()

      显示图片

      1
      2
      3
      4
      5
      # 创建黑白照片(二维)
      boy = np.array([[0.21,0.14,0.132,0.142],
      [0.21,0.14,0.132,0.142],
      [0.21,0.14,0.132,0.142],
      ])
      1
      2
      plt.imshow(boy, cmap='gray') # cmap:灰度级
      plt.show()
      1
      2
      3
      4
      # 切片处理
      g = girl[:300,700:950]
      plt.imshow(g)
      plt.show()
    2. 使用 np 的 routines 函数创建

      • np.ones(shape,dtype=None,order='C'):元素全为 1

        1
        2
        # 参数shape数据的形状,参数传一个元组,元组的第0个元素代表第0维中的元素个数,依次类推
        np.ones((3,2,4))
        1
        2
        ones = np.ones((168,59,3))
        plt.show()
        1
        2
        ones[:,:,1:] = 0 # 数组是可以切片赋值的
        ones
      • np.zeros(shape,dtype="float",order="C"):元素全为 0

        1
        np.zeros((2,3),dtype='int32')
      • np.full(shape,fill_value,dtype=None):填充

        1
        np.full((3,4),12,dtype='float')
      • np.eye(N,M,k=0,dtype='float')

        1
        np.eye(4) # 创建4*4的单位矩阵
      • np.linspace(start,stop,num=50)

        1
        2
        np.linspace(0,10,11) # 0-10平均划分出11个数
        np.logspace(1,100,10) # 对数划分
      • np.arange([start,]stop,[step,]dtype=None) "[]"中是可选项

        1
        np.arange(0,100,5) # 0-100每隔5个取一个
      • np.random.randint(low,high=None,size=None,dtype='I')

        1
        np.random.randint(1,10,size=(2,2)) # 随机生成1-10的2行2列数组

        low 下限;high 上限;size 形状(元组)

      • np.random.randn(d0,d1,...,dn) :从第一维度到第 n 维度生成一个数组,数组中的数字符合标准正态分布

        1
        np.random.randn(5,6,2) # 标椎正太分布N(0,1)
      • np.random.normal(loc=0.0,scale=1.0,size=None)

        1
        np.random.normal(450,10,size=(90)) # 一般正太分布N(a,b)
      • np.random.random(size=None)

        1
        np.random.random(size=(10)) # 随机生成0-1之间的浮点数
      • 用随机数生成图片

        1
        2
        3
        boy = np.random.random((337,480,3))
        plt.imshow(boy)
        plt.show()
  • ndarray 的属性

    • 数组的常用属性:维度 ndim, 大小 size, 形状 shape, 元素类型 dtype, 每项大小 itemsize, 数据 data
  • ndarray 的基本操作

    1. 索引

      1
      2
      nd = np.random.randint(0,10,size=(6,6))
      nd
      1
      2
      3
      nd[0][1]
      nd[0,1] # 先访问第0个维度的第0个,再访问第一个维度的第一个
      nd[1,2,3] # 维度不足3个,不能这样访问
      1
      nd[1,4] = 20000 # 修改
      1
      2
      3
      nd[[1,4]] # 取第一行和第四行
      nd[[1,1,1,1,1,1]] # 全部取第一行
      nd[[1,4,5,2,0]] # 连续访问多个,可以把你要访问的下标写成一个列表
    2. 切片

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      nd = np.random.randint(0,10,size=(4,4))
      nd
      nd[0:3] # 区间是左闭右开,如果右边超过范围取全部
      nd[:4:2] # 隔两个取一个
      nd[4:0:-2] # 倒着取
      nd[::-1] # 逆序
      nd[:,0:2] # 第一个维度不动,动第二个维度
      g2 = girl[::-1] # 把girl调头,上下翻转
      g2 = girl[::-2] # 高减半,宽不变
      g2 = girl[:,::-1] # 左右翻转
      g2 = girl[:,:,::-1] # 反色
      plt.imshow(g2)
      plt.show()
    3. 变形

      1
      2
      reshape() # 对数组进行变形,元素总数不一致,不能相互转换
      resize() # 同上

      1. 都是对数组进行形变,resize () 是在原来的数组上直接形变,reshape () 生成一个新数组
      2. 变形的时候,新数组的总元素个数要和原来的保持一致

      1
      2
      3
      4
      5
      6
      7
      # 拼图
      girl = plt.imread('./source/girl2.jpg')
      plt.imshow(girl)
      plt.show()
      tiger[200:500,250:550] = girl
      plt.imshow(tiger)
      plt.show()
    4. 级联

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      # 按照指定的维度把两个数组链接在一起
      nd1 = np.random.randint(0,100,size=(4,4))
      nd2 = np.random.randint(0,100,size=(4,3))
      print(nd1)
      print(nd2)
      np.concatenate([nd1,nd2],axis=1)
      # 参数一,参与级联的那些数组;参数二,级联的维度
      nd3 = np.random.randint(0,100,size=(6,4))
      print(nd3)
      np.concatenate([nd1,nd3])

      1. 参与级联的数组要构成一个列表(或元组)
      2. 维度必须一样
      3. 形状必须相符(如:二维数组 axis=0 时,列数必须一样;axis=1 时行数必须一样)
      4. 级联的默认方向是 shape 的第一个值所代表的的那个维度(axis 默认为 0)

      1
      2
      np.vstack(nd3) # 把行数组改成列数组(把所有列上的数组拼接成一个一列的数组)
      np.hstack(nd3) # 把列数组改成行数组(把所有行上的数组拼接成一个一行的数组)
    5. 切分

      1
      2
      3
      4
      5
      6
      7
      nd = np.random.randint(0,100,size=(5,6))
      print(nd)
      np.split(nd,[1,4],axis=0) # 效果同np.vsplit(nd,[1,4])
      np.split(nd,[1,4],axis=1) # 效果同np.hsplit(nd,[1,4])
      np.vsplit(nd,[1,4]) # 纵向上切分
      np.hsplit(nd,[1,4]) # 水平方向上切分
      # 参数一,被切的数组;参数二,切分点(列表,在切分点前面切分)
    6. 副本

      1
      2
      3
      4
      5
      6
      7
      8
      nd1 = nd # 此时nd1和nd引用的是同一个数组对象(nd和nd1中存储的地址是一样的)
      # 在某种意义上这也是一种浅拷贝
      nd2 = nd.copy() # 将nd拷贝一份给nd2,深拷贝
      l = [1,2,3,4]
      nd = np.array(1) # 把l拷贝了一份放在了数组nd中
      nd[0] = 100
      nd
      l
  • ndarray 的聚合操作

    1. 求和

      1
      2
      3
      4
      5
      6
      nd = np.random.randint(0,10,size=(3,3))
      nd
      np.sum(nd,axis=0) # 把行按照列标对应相加
      np.sum(nd,axis=1) # 把列按照行标对应相加
      np.sum(nd) # 把所有元素相加
      nd.sum() # 把所有元素相加
    2. 最值

      1
      2
      3
      4
      5
      6
      7
      8
      nd.max()
      np.max(nd)
      np.max(nd,axis=0) # 求每列里面的最大值
      np.max(nd,axis=1) # 求每一行的最大值
      np.argmax(nd) # 最大值下标
      np.argmin(nd) # 最小值下标
      np.argmax(nd,axis=0) # 每列最大值下标组成的列标
      np.argmax(nd,axis=1) # 每行最大值下标组成的列标
    3. 其他聚合操作

      1
      2
      3
      4
      5
      nd = np.array([1,2,3,np.nan])
      np.nan + 100
      mp.nan * 100
      # nan表示缺失(默认是浮点型),缺失和任何数做算数运算都是缺失(nan)
      np.nansum(nd) # 以nan开头的聚合方法,可在聚合运算的时候直接把nan剔除
    4. 思考题:

      • 给定一个 4 维矩阵,如何得到最后两维的和?

        1
        2
        3
        4
        5
        nd = np.random.randint(0,10,size=(2,3,2,2))
        nd
        nd.sum(axis=-1)
        nd.sum(axis=-2)
        nd.sum(axis=(-1,-2))
      • 思考题:如何根据第 3 列来对一个 5*5 矩阵排序?

        1
        2
        3
        4
        5
        6
        nd = np.random.randint(0,20,size=(5,5))
        nd
        nd[[4,1,3,2,0]] # 如何根据顺序求出第三列下表?
        sort_ind = np.argsort(nd[:,3]) # 对第三进行排序,并获得其下标
        sort_ind
        nd[sort_ind]
  • ndarray 的矩阵操作

    1. 基本矩阵操作

      • 算术运算(即加减乘除)

        1
        2
        3
        4
        5
        nd = np.random.randint(0,10,size=(5,5))
        nd
        nd + 3 # 每个元素加3(启动广播机制,把缺失的地方补全)
        nd * 2 # 乘法不需要哦广播机制
        nd / 2
      • 矩阵积

        1
        2
        3
        4
        5
        nd1 = np.random.randint(0,5,size=(4,3))
        nd2 = np.random.randint(0,5,size=(3,4))
        print(nd1)
        print(nd2)
        np.dot(nd1,nd2)
    2. 广播机制

      • ndarray 的广播机制的两条规则:
        1. 为缺失维度补 1
        2. 假定缺失的元素用已有值填充
          1
          2
          3
          4
          5
          6
          m = np.random.randint(0,10,size=(2,3))
          m
          a = np.arange(3)
          a
          # 求m + a
          m + a
          1
          2
          3
          4
          5
          6
          7
          8
          9
          10
          a = np.arange(3).reshape(3,1)
          a
          b = np.arange(3)
          b
          a + b
          ‘’‘
          0 0 0 0 1 2
          1 1 1 + 0 1 2
          2 2 2 0 1 2
          ’‘’
          1
          a + 3 # 常数缺行缺列,补行补列

          如果行和列个数均不相同无法补全,即不能相加

  • 排序

    1
    2
    3
    4
    5
    6
    7
    nd = np.random.randint(0,100,size=(10))
    nd.sort() # 改变原来的数组
    np.sort(nd) # 不会改变原来的数组而是生成一个新的数组
    nd1 = np.random.randint(0,100,size=(4,4))
    np.sort(nd1, axis=1) # axis=1排的是列标,默认值(每一行进行排序)
    np.sort(nd1, axis=0) # axis=0排的是行标(每一列进行排序)
    np.argsort(nd1,axis=0) # argsort()排的是下标
  • 人脸识别

    • 使用 pip -V 查看 pip 是否在 Anaconda3 下,如果是继续往下执行
    • 安装:pip install opencv-python
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      import cv2
      # opencv是计算机视觉库
      import matplotlib.pyplot as plt
      %matplotlib inline
      # 这个魔法指令在程序的结束加上一个plt.show()
      an = plt.imread("./cv2_change_head/ab.jpg")
      # 创建一个cv2的分类器,用于识别图片
      case = cv2.CascadeClassifier()
      # 给case加上人脸识别的算法
      case.load("./cv2_change_head/haarcascade_frontalface_default.xml")
      # 加上这个算法以后,case就可以识别人脸的位置
      # 用case来识别人脸
      face = case.detectMultiScale(an)
      face
      dog = plt.imread("./cv2_change_head/dog.jpg")
      dog.shape
      small_dog = cv2.resize(dog,(117,117))
      plt.imshow(small_dog)
      an[72:189,61:178] = small_dog
      plt.imshow(an)