专栏首页大龄程序员的人工智能之路[机器学习实战札记] NumPy基础

[机器学习实战札记] NumPy基础

<<机器学习实战>>一书非常注重实践,对每个算法的实现和使用示例都提供了python实现。在阅读代码的过程中,发现对NumPy有一定的了解有助于理解代码。特别是NumPy中的数组和矩阵,对于初次使用者而言,有点难以理解。下面就总结一下NumPy基础知识。

NumPy和SciPy、Scikit-learn、pandas等库一样,是数据科学领域不可或缺的库,它提供了比python list更好的数组数据结构:更紧凑、读写速度更快、更加方便和高效。NumpPy包含两种基本的数据类型:数组和矩阵,二者在处理上稍有不同。

NumPy数组

NumPy数据处理

与标准的python不同,使用NumPy处理数组中的数据可以省去循环语句。比如:

>>> import numpy as np
>>> mm = np.array([1, 1, 1])
>>> pp = np.array([1, 2, 3])
>>> mm + pp
array([2, 3, 4])

不需要循环,就像两个平常的两个数,做加法就可以完成数组的相加。

另外还有一些操作,在NumPy中能够简单的完成,比如在每个元素上乘以常量2,可以写成:

>>> pp * 2
array([2, 4, 6])

对每个元素平方,这在K-近邻算法中用到:

>>> pp ** 2
array([1, 4, 9])

两个数组相乘,即两个数组(数组维度必须相同)的元素对应相乘:

>>> a1 = np.array([1, 2, 3])
>>> a2 = np.array([0.3, 0.2, 0.3])
>>> a1 * a2
array([0.3, 0.4, 0.9])

NumPy数组属性

一个numpy数组是一个由不同数值组成的网格,网格中的数据都是同一种数据类型,可以通过非负整型数的元组来访问。

  • data 代表数组第一个字节的内存地址
  • dtype 描述元素的数据类型
  • shape 描述数组维度上的大小,它是一个元组,即使是一维数组
  • strides 描述从一数组元素到下一数组元素在内存中要前进的字节数,它也是一个元组,strides值与数据类型和数组维度大小有关。比如strides值为(10, 1)意味着前进1个字节获得下一列的数据,而前进10个字节定位到下一行数据。
>>> my_2d_array = np.array([[1, 2, 3, 4], [5, 6, 7, 8]], dtype=np.int64)
>>> print(my_2d_array.data)
<memory at 0x7fdd8c0e4480>
>>> print(my_2d_array.shape)
(2, 4)
>>> print(my_2d_array.dtype)
int64
>>> print(my_2d_array.strides)
(32, 8)

NumPy中也支持多维数组,多维数组中的元素也可以像列表中一样访问:

>>> jj = np.array([[1, 2, 3], [1, 1, 1]])
>>> jj[0]
array([1, 2, 3])
>>> jj[0][1]
2

也可以用矩阵方式访问:

>>> jj[0, 1]
2

创建数组

我们可以从列表,通过np.array()函数创建数组,然后利用方括号访问其中的元素,array()函数还可以增加一个可选的参数,指明数组元素的数据类型:

import numpy as npa = np.array([1,2,3,4], dtype=np.int64)
print ab = np.array([[1,2,3],[4,5,6]])   # Create a rank 2 array
print b                          
print b.shape                     # Prints "(2, 3)"
print b[0, 0], b[0, 1], b[1, 0]   # Prints "1 2 4"

结果:

[1 2 3 4]
[[1 2 3]
[4 5 6]]
(2, 3)
1 2 4

Numpy还提供了很多其他创建数组的方法:

import numpy as npa = np.zeros((2,2))  # Create an array of all zeros
print a              # Prints "[[ 0.  0.]
                    #          [ 0.  0.]]"b = np.ones((1,2))   # Create an array of all ones
print b              # Prints "[[ 1.  1.]]"c = np.full((2,2), 7) # Create a constant array
print c               # Prints "[[ 7.  7.]
                     #          [ 7.  7.]]"d = np.eye(2)        # Create a 2x2 identity matrix
print d              # Prints "[[ 1.  0.]
                    #          [ 0.  1.]]"e = np.random.random((2,2)) # Create an array filled with random values
print e                     # Might print "[[ 0.91940167  0.08143941]
                           #               [ 0.68744134  0.87236687]]"

注意,np.eye()和np.identity()函数用于创建单位矩阵,所谓单位矩阵,就是矩阵的主对角线上的元素都为1, 而其它元素都为0,矩阵和单位矩阵相乘,积不变。

在<<机器学习实战>>中还使用到了np.tile函数,其定义如下:

numpy.tile(A, reps)

重复reps次A,形成一个数组。这里reps可以是数字,也可以是元组。示例如下:

>>> a = np.array([0, 1, 2])
>>> np.tile(a, 2)
array([0, 1, 2, 0, 1, 2])
>>> np.tile(a, (2, 2))
array([[0, 1, 2, 0, 1, 2],
      [0, 1, 2, 0, 1, 2]])
>>> np.tile(a, (2, 1, 2))
array([[[0, 1, 2, 0, 1, 2]],
      [[0, 1, 2, 0, 1, 2]]])

注意多维数组,经过多维的扩充:

>>> b = np.array([[1, 2], [3, 4]])
>>> np.tile(b, 2)
array([[1, 2, 1, 2],
      [3, 4, 3, 4]])
>>> np.tile(b, (2, 1))
array([[1, 2],
      [3, 4],
      [1, 2],
      [3, 4]])

是不是结果有点出乎意料,多尝试一下就可以理解其中的扩充逻辑了。

NumPy矩阵

矩阵的关键字matrix也可以简写为mat:

>>> ss = np.mat([1, 2, 3])
>>> ss
matrix([[1, 2, 3]])
>>> mm = np.matrix([1, 2, 3])
>>> mm
matrix([[1, 2, 3]])

访问矩阵中的单个元素:

>>> mm[0, 1]
2

注意矩阵的乘法含义,比如1x3的矩阵是不能与1x3的矩阵相乘的。比如ss乘以mm,会出现如下错误,必须将其中一个转置:

>>> mm * ss
Traceback (most recent call last):
 File "/home/alex/anaconda3/lib/python3.6/site-packages/IPython/core/interactiveshell.py", line 2910, in run_code
   exec(code_obj, self.user_global_ns, self.user_ns)
 File "<ipython-input-50-7262af0f2071>", line 1, in <module>
   mm * ss
 File "/home/alex/anaconda3/lib/python3.6/site-packages/numpy/matrixlib/defmatrix.py", line 309, in __mul__
   return N.dot(self, asmatrix(other))
ValueError: shapes (1,3) and (1,3) not aligned: 3 (dim 1) != 1 (dim 0)>>> mm * ss.T
matrix([[14]])

其中.T方法完成了ss的转置。

要实现数组那样的相乘,可以通过multiply函数实现:

>>> np.multiply(mm, ss)
matrix([[1, 4, 9]])

排序

sort()方法用于排序,在原地进行,这意味着排序后的结果占用原始的存储空间,如果希望保留数据的原序,必须事先做一份拷贝。

argsort()方法得到矩阵中每个元素的排序序号:

>>> dd = np.mat([4, 5, 1])
>>> dd.argsort()
matrix([[2, 0, 1]])
>>> dd.sort()
>>> dd
matrix([[4, 5, 1]])

索引

对于矩阵,如果想取出其中一行的元素,可以使用:操作符和行号来完成:

>>> jj = np.mat([[1, 2, 3], [8, 8, 8]])
>>> jj[1, :]
matrix([[8, 8, 8]])

也可以指定范围:

>>> jj[1, 0:2]
matrix([[8, 8]])

注意,这个范围是前闭后开,比如0:2并不包括索引值为2的元素,索引值也可以超过该维度的大小,比如:

>>> jj[1, 0:3]
matrix([[8, 8, 8]])
>>> jj[1, 0:4]
matrix([[8, 8, 8]])

参考

  1. Python Numpy Array Tutorial
  2. CS231n课程笔记翻译:Python Numpy教程
  3. <<机器学习实战>>,p298 ~ p301
  4. NumPy v1.13 Manual

本文分享自微信公众号 - 云水木石(ourpoeticlife),作者:云水木石

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2018-03-15

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 使用TensorFlow一步步进行目标检测(5)

    本教程进行到这一步,您选择了预训练的目标检测模型,转换现有数据集或创建自己的数据集并将其转换为TFRecord文件,修改模型配置文件,并开始训练模型。接下来,您...

    云水木石
  • 人工智能、机器学习和深度学习

    [注: 本文翻译自网上的一篇文章,有删节,原文:https://medium.com/iotforall/the-difference-between-arti...

    云水木石
  • 从人工智能鉴黄模型,尝试TensorRT优化

    随着互联网的快速发展,越来越多的图片和视频出现在网络,特别是UCG产品,激发人们上传图片和视频的热情,比如微信每天上传的图片就高达10亿多张。每个人都可以上传,...

    云水木石
  • numpy在cs231n中的应用

    0.作者的话1.访问数组2.broadcast机制3.np.bincount()4.np.argmax()5.联合求解6.求取精度7.作者的话

    公众号guangcity
  • 【玩转腾讯云】深度学习之《深度学习入门》学习笔记(一)Python入门

    最近学习吴恩达《Machine Learning》课程以及《深度学习入门:基于Python的理论与实现》书,一些东西总结了下。现就后者学习进行笔记总结。本文是本...

    ZNing
  • 技术角 | 深度学习之《深度学习入门》学习笔记(一)Python入门

    最近学习吴恩达《Machine Learning》课程以及《深度学习入门:基于Python的理论与实现》书,一些东西总结了下。现就后者学习进行笔记总结。本文是本...

    ZNing
  • 数据分析 ———— numpy基础(一)

    准备了好长时间,想要写点关于数据分析的文章,但一直忙于工作,忙里抽闲更新一篇关于numpy的文章。

    andrew_a
  • 卧谈会之numpy

    0.月总结1.访问数组2.broadcast机制3.np.bincount()4.np.argmax()5.联合求解6.作者的话

    公众号guangcity
  • 说声谢谢!给你需要的NumPy知识

    Python虽然是一门比较好入门的语言,相较于其他语言来说是一门比较简单的语言。不过有一个很重要的问题就是,即使Python 语言的很多方法不用手打都已经被封装...

    小小科
  • Numpy基础知识点汇总

    1、概述 Numpy是高性能科学计算和数据分析的基础包,它的部分功能如下: 1)ndarray,一个具有矢量算术运算和复杂广播能力的快速且节省空间的多维数组。 ...

    石晓文

扫码关注云+社区

领取腾讯云代金券