人工智能之Numpy与Pandas培训文档
创建时间:2018-09-09  访问量:2895  4  0

人工智能之Numpy与Pandas培训文档

数组与标量、数组与数组之间的操作

1、数组不用循环即可对每个元素执行批量运算,这通常就叫做矢量化,即用数组表达式代替循环的做法。

2、矢量化数组运算性能要比纯Python方式快上一两个数量组。

3、大小相等的数组之间的任何算述运算都会将运算应用到元素组。

 

Numpy的算术运算

数组与标量的算术运算

>>> import numpy as np # 导入numpy
>>> array1 = np.arange(15).reshape(3,5) # 创建一个3行5列的ndarray数组
>>> array1 # array1 结果
array([[ 0,  1,  2,  3,  4],
       [ 5,  6,  7,  8,  9],
       [10, 11, 12, 13, 14]])
>>> array2 = array1 + 4 # 将数组array1 + 4
>>> array2 # 输入array2的结果
array([[ 4,  5,  6,  7,  8],
       [ 9, 10, 11, 12, 13],
       [14, 15, 16, 17, 18]])
>>> array21 = array1 - 5 # 将数组array1 - 5
>>> array21
array([[-5, -4, -3, -2, -1],
       [ 0,  1,  2,  3,  4],
       [ 5,  6,  7,  8,  9]])

由上面的代码运行结果可以看出,数组与标量相加,是将数组中的每个元素都与这个常量相加。数组与标量加减,是将数组中的每个元素都与这个常量相减。

>>> array22 = array1 * 3 # 将数组array1 乘以3
>>> array22
array([[ 0,  3,  6,  9, 12],
       [15, 18, 21, 24, 27],
       [30, 33, 36, 39, 42]])
>>> array23 = array1 / 2 # 将数组array1 除以2
>>> array23 # / 是整数截断相除,只会得到商,不会得到余数,所以1/2 == 0的,因为商是0
array([[0, 0, 1, 1, 2],
       [2, 3, 3, 4, 4],
       [5, 5, 6, 6, 7]])

由以上代运行结果可知,数组与标量相乘或相除,都是将这个数组的每个元素与标量相乘或相除。

数组与数组的算术运算

>>> array1
array([[ 0,  1,  2,  3,  4],
       [ 5,  6,  7,  8,  9],
       [10, 11, 12, 13, 14]])
>>> array2
array([[ 4,  5,  6,  7,  8],
       [ 9, 10, 11, 12, 13],
       [14, 15, 16, 17, 18]])
>>> array3 = array1 + array2
>>> array3
array([[ 4,  6,  8, 10, 12],
       [14, 16, 18, 20, 22],
       [24, 26, 28, 30, 32]])
>>>

继上述代码,再将两个数组相加得到array3,array3是array1与array2这两个数组中的每个元素相加而成。array1与array2的形状是一样的。如果不一样行不行呢?我们试一下吧!

>>> array4 = array3.reshape(5,3) # 将array3重塑成5行3列赋给array4
>>> array4
array([[ 4,  6,  8],
       [10, 12, 14],
       [16, 18, 20],
       [22, 24, 26],
       [28, 30, 32]])
>>> array5 = array3 + array4 # array3与array4的形状不一样,结果报错
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: operands could not be broadcast together with shapes (3,5) (5,3)
>>>

事实证明,两个数组进行加法运算必须具有相同的形状。下面看一下两个数组相除和相乘。

>>> array1
array([[ 0,  1,  2,  3,  4],
       [ 5,  6,  7,  8,  9],
       [10, 11, 12, 13, 14]])
>>> array2
array([[ 4,  5,  6,  7,  8],
       [ 9, 10, 11, 12, 13],
       [14, 15, 16, 17, 18]])
>>> array5 = array2 / array1 # 因为数组1中包含0所以会出现警告
__main__:1: RuntimeWarning: divide by zero encountered in divide
>>> array5 = array2 / array1
>>> array5 # 除以0的结果是0,这是由numpy自动处理的,并不会报错
array([[0, 5, 3, 2, 2],
       [1, 1, 1, 1, 1],
       [1, 1, 1, 1, 1]])
>>> array5 = array1 / array2 # 将array1与array2中的每个对应元素相除
>>> array5 # 结果都是零,因为array2中的每个元素都比array1中大,只取商,所有都是0
array([[0, 0, 0, 0, 0],
       [0, 0, 0, 0, 0],
       [0, 0, 0, 0, 0]])
>>> array11 = array1.astype(float) # 因此,为了看到效果,我们将array1的元素类型转成浮点型
>>> array5 = array11 /array2 # 再将元素为float类型的数组array11除以数组array2
>>> array5 # 结果就是float64类型,因此可以得到正确结果
array([[0.        , 0.2       , 0.33333333, 0.42857143, 0.5       ],
       [0.55555556, 0.6       , 0.63636364, 0.66666667, 0.69230769],
       [0.71428571, 0.73333333, 0.75      , 0.76470588, 0.77777778]])
>>>

我们再来看一个数组的除法运算:

>>> array6 = array2 / array11 # array11元素类型为float,因此除以0时,会出现inf(无穷大)
>>> array6
array([[       inf, 5.        , 3.        , 2.33333333, 2.        ],
       [1.8       , 1.66666667, 1.57142857, 1.5       , 1.44444444],
       [1.4       , 1.36363636, 1.33333333, 1.30769231, 1.28571429]])
>>> from __future__ import division # 引入python3中的除法特性
>>> array2 / array1 # array2 / array1,当array1中有元素为0时,不是显示0,而是显示inf(无穷大)
array([[       inf, 5.        , 3.        , 2.33333333, 2.        ],
       [1.8       , 1.66666667, 1.57142857, 1.5       , 1.44444444],
       [1.4       , 1.36363636, 1.33333333, 1.30769231, 1.28571429]])

在Python2中,两个ndarray数组相除,遇到除数为0时,整型为报错,当有一个元素是浮点型是,会计算得到inf(无穷大),如果引用python3中的特性的话,整数除以0,也不会报错,会显示inf。

注意:

数组的算术运算,必须保证两边的形状相同。

 

元素级的运算

1、像上面例子展现出来的,加、减、乘、除幂运算等,可以用于数组与标量、大小相等的数组之间。

2、在Numpy中,大小(形状)相等的数组之间的运算,是为元素级的运算,即只用于位置相同的元素之间的运算,所得到的运算结果组成一个新数组,运算结果的位置跟操作数位置相同。

 

有的看官就在想了,我如果把二维数组看成矩阵,要计算两个矩阵之间的点积怎么算呢?矩阵的点积即一个m x n的矩阵(其实就是形状为(m,n)的ndarray),与一个n x p的矩阵相乘,得到一个m x p的矩阵。下面具体来讲。

 

ndarray二维数组的矩阵积

介绍: 

  • 两个二维矩阵(多维数组即矩阵)满足第一个矩阵的列数与第二个矩阵的行数相同,那么可以进行矩阵乘法,即矩阵积,矩阵积不是元素级的运算(对应位置元素的计算)。
  • 两个矩阵相乘结果所得到的数组中每个元素为,第一个矩阵中与该元素行号相同的元素和第二个矩阵中与该元素列号相同的元素,两两要乘后求和得到元素结果。

这个计算可以复习下线性代数中知识,下面举例简要讲解下:

例:一个2行3列的矩阵与一个3行4列的矩阵点积的计算:

>>> metrix1 = np.arange(6).reshape(2,3) # 创建一个2行3列的矩阵
>>> metrix1
array([[0, 1, 2],
       [3, 4, 5]])
>>> metrix2 = np.arange(12).reshape(3,4) # 创建一个3行4列的矩阵
>>> metrix2
array([[ 0,  1,  2,  3],
       [ 4,  5,  6,  7],
       [ 8,  9, 10, 11]])
>>> metrix3 = metrix1.dot(metrix2) # 使用ndarray对象的dot方法计算矩阵点积
>>> metrix3
array([[20, 23, 26, 29],
       [56, 68, 80, 92]])

首先,我们看看矩阵的形状,metrix1(2,3) x metrix2(3,4) = metrix3(2,4)。

metrix1的列与metrix2的行相等,得到结果metrix3矩阵的形状是metrix1的行(2)与metrix2中的列(4)组成的形状。

计算方法是:

metrix1的行中每个元素,与metrix2中对应列的每个元素相乘后求和作为结果矩阵对应位置上的元素。我们说具体一点:metrix1的第1行与metrix2的第1列对应的元素相乘求和作为metrix3的第1行第1列的元素。metrix1的第1行与metrix2的第2列对应元素相乘后求和作为metrix3的第1行第2列,依次类推。

如:20 = 0*0 + 1 * 4 + 2 * 8;23 = 0 * 1 + 1 * 5 + 2 * 9;明白吗?还不懂?线性代数,我不是砖家,也说不好。

看个现实生活中的例子:

这两个表的数组作点积得出另一张表具有什么意义?是不是得到每个部门对应所有产品的总金额与产品总体积(这难道不就是个统计吗)?评论区见!(图中下面一句话可作参考)

 

介绍下行轴与列轴

矩阵的行称为列轴,矩阵的列称为行轴,就是这么说的,我也没查证,大家可以查一下。