前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >[机器学习实战札记] NumPy基础

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

作者头像
云水木石
发布2019-07-02 14:40:55
5190
发布2019-07-02 14:40:55
举报

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

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

NumPy数组

NumPy数据处理

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

代码语言:javascript
复制
>>> import numpy as np
>>> mm = np.array([1, 1, 1])
>>> pp = np.array([1, 2, 3])
>>> mm + pp
array([2, 3, 4])

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

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

代码语言:javascript
复制
>>> pp * 2
array([2, 4, 6])

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

代码语言:javascript
复制
>>> pp ** 2
array([1, 4, 9])

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

代码语言:javascript
复制
>>> 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个字节定位到下一行数据。
代码语言:javascript
复制
>>> 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中也支持多维数组,多维数组中的元素也可以像列表中一样访问:

代码语言:javascript
复制
>>> jj = np.array([[1, 2, 3], [1, 1, 1]])
>>> jj[0]
array([1, 2, 3])
>>> jj[0][1]
2

也可以用矩阵方式访问:

代码语言:javascript
复制
>>> jj[0, 1]
2
创建数组

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

代码语言:javascript
复制
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"

结果:

代码语言:javascript
复制
[1 2 3 4]
[[1 2 3]
[4 5 6]]
(2, 3)
1 2 4

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

代码语言:javascript
复制
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函数,其定义如下:

代码语言:javascript
复制
numpy.tile(A, reps)

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

代码语言:javascript
复制
>>> 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]]])

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

代码语言:javascript
复制
>>> 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:

代码语言:javascript
复制
>>> ss = np.mat([1, 2, 3])
>>> ss
matrix([[1, 2, 3]])
>>> mm = np.matrix([1, 2, 3])
>>> mm
matrix([[1, 2, 3]])

访问矩阵中的单个元素:

代码语言:javascript
复制
>>> mm[0, 1]
2

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

代码语言:javascript
复制
>>> 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函数实现:

代码语言:javascript
复制
>>> np.multiply(mm, ss)
matrix([[1, 4, 9]])
排序

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

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

代码语言:javascript
复制
>>> dd = np.mat([4, 5, 1])
>>> dd.argsort()
matrix([[2, 0, 1]])
>>> dd.sort()
>>> dd
matrix([[4, 5, 1]])
索引

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

代码语言:javascript
复制
>>> jj = np.mat([[1, 2, 3], [8, 8, 8]])
>>> jj[1, :]
matrix([[8, 8, 8]])

也可以指定范围:

代码语言:javascript
复制
>>> jj[1, 0:2]
matrix([[8, 8]])

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

代码语言:javascript
复制
>>> 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
本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2018-03-15,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 云水木石 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • NumPy数组
    • NumPy数据处理
      • NumPy数组属性
        • 创建数组
        • NumPy矩阵
          • 排序
            • 索引
            • 参考
            领券
            问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档