克隆策略

Numpy是高性能科学计算和数据分析的基础包,是Python在科学计算领域使用最广的一个包。

1、ndarray数组基础

Pyhton 中用列表保存一组值,可将列表当成是数组使用。此外,Python 有 array 模快,但他不支持多维数组,无论是列表还是 array 模块都没有科学运算函数,不适合做矩阵等科学计算。因此,Numpy没有使用 Python 本身的数组机制,而是提供了 ndarray 数组对象,该对象能方便的存取数组,而且拥有丰富的数组计算函数,比如向量的加法、减法、乘法等。

使用 ndarray 数组,首先需要导入 Numpy 函数库,也可以直接导入该函数库:

In [1]:
from numpy import *

使用别名导入

In [2]:
import numpy as np

1.1 创建数组

创建数组是进行数组计算的先决条件,可以通过array()函数定义数组实例对象,其参数为Python 的序列对象(比如列表。)如果想定义多维数组,则传递多层嵌套的序列。例如下面这条语句定义了一个二维数组,其大小为(2,3),即有2行,3列。

In [3]:
a = np.array([[1,2,4.0],[3,6,9]])
a
Out[3]:
array([[ 1.,  2.,  4.],
       [ 3.,  6.,  9.]])

接着我们看下数组的一些属性:

In [4]:
# 查看行数
a.ndim
Out[4]:
2
In [5]:
# 查看数组的维数,返回(n,m), 其中 n 为行数,m 为列数。
a.shape
Out[5]:
(2, 3)
In [6]:
# 查看元素的类型,比如 numpy.int32、numpy.float64
a.dtype
Out[6]:
dtype('float64')

1.2 特殊数组

Numpy的特殊数组主要有以下几种:

  • zeros数组:全零数组,元素全为0;
  • ones数组:全1数组,元素全为1;
  • empty数组:空数组,元素全近似为0;

下面是全零、全1、空数组的创建方法:

In [7]:
np.zeros((2,3))
Out[7]:
array([[ 0.,  0.,  0.],
       [ 0.,  0.,  0.]])
In [8]:
np.ones((3,5))
Out[8]:
array([[ 1.,  1.,  1.,  1.,  1.],
       [ 1.,  1.,  1.,  1.,  1.],
       [ 1.,  1.,  1.,  1.,  1.]])
In [9]:
np.empty((3,3))
Out[9]:
array([[  6.90771382e-310,   6.90771382e-310,   6.90771382e-310],
       [  6.90771382e-310,   6.90776702e-310,   6.90776702e-310],
       [  6.90776702e-310,   6.90776702e-310,   6.90776702e-310]])

1.3 序列数组

arange函数:他与 Python 的 range 函数相似,但他属于Numpy 库,其参数依次为:开始值、结束值、步长。

In [10]:
np.arange(1,20,5)
Out[10]:
array([ 1,  6, 11, 16])

我们还可以使用 linspace 函数创建等差序列数组,其参数依次为:开始值、结束值、元素数量。

In [11]:
np.linspace(0,2,9)
Out[11]:
array([ 0.  ,  0.25,  0.5 ,  0.75,  1.  ,  1.25,  1.5 ,  1.75,  2.  ])

1.4 数组索引

Numpy 数组的每个元素、每行元素、每列元素都可以用索引访问,不过注意:索引是从 0 开始的。 其操作与列表基本相同。

In [12]:
a = np.array([[1,2,4.0],[3,6,9]])
a
Out[12]:
array([[ 1.,  2.,  4.],
       [ 3.,  6.,  9.]])
In [13]:
# 取 a 的第一行元素
a[0]
Out[13]:
array([ 1.,  2.,  4.])
In [14]:
# 取 a 的第二列元素
a[:,1]
Out[14]:
array([ 2.,  6.])
In [15]:
# 取 a 的第一行的第三个元素
a[0,2]
Out[15]:
4.0

1.5 数组运算

In [16]:
a = np.array([1,2,3])
b = np.array([4.,5,6])
In [17]:
# 加法运算
a + b
Out[17]:
array([ 5.,  7.,  9.])
In [18]:
# 减法运算
a - b
Out[18]:
array([-3., -3., -3.])
In [19]:
# 乘法运算
a * b
Out[19]:
array([  4.,  10.,  18.])
In [20]:
# 乘方运算:a的2次方
a ** 2
Out[20]:
array([1, 4, 9])
In [21]:
# 除法运算
a/b
Out[21]:
array([ 0.25,  0.4 ,  0.5 ])
In [22]:
# 数组点乘
np.dot(a,b)
Out[22]:
32.0
In [23]:
# 判断大小,返回 bool 值
a >= 2
Out[23]:
array([False,  True,  True], dtype=bool)
In [24]:
# a中最大的元素
a.max()
Out[24]:
3
In [25]:
# a中最小的元素
a.min()
Out[25]:
1
In [26]:
# a的和
a.sum()
Out[26]:
6

1.6 数组拷贝

数组的拷贝分为浅拷贝和深拷贝两种,浅拷贝通过数组变量的复制完成,深拷贝使用数组对象的copy方法完成。

浅拷贝只拷贝数组的引用,如果对拷贝对象修改。原数组也将修改。

下面的代码演示了浅拷贝的方法:

In [27]:
a = np.ones((2,3))
a
Out[27]:
array([[ 1.,  1.,  1.],
       [ 1.,  1.,  1.]])
In [28]:
# b 为 a 的浅拷贝
b = a
b
Out[28]:
array([[ 1.,  1.,  1.],
       [ 1.,  1.,  1.]])
In [29]:
# 对 b 进行修改,a 也会被修改
b[1,2] = 9
a
Out[29]:
array([[ 1.,  1.,  1.],
       [ 1.,  1.,  9.]])

深拷贝会复制一份和原数组一样的数组,但他们在内存中是分开存放的,所以改变拷贝数组,原数组不会改变。

下面的代码演示了 b 使用 copy 方法从原数组 a 复制一份拷贝的情况。

In [30]:
a = np.ones((2,3))
a
Out[30]:
array([[ 1.,  1.,  1.],
       [ 1.,  1.,  1.]])
In [31]:
b = a.copy()
b[1,2] = 9
b
Out[31]:
array([[ 1.,  1.,  1.],
       [ 1.,  1.,  9.]])
In [32]:
a
Out[32]:
array([[ 1.,  1.,  1.],
       [ 1.,  1.,  1.]])

2、矩阵

2.1 创建矩阵

Numpy的矩阵对象与数组对象相似,主要不同之处在于,矩阵对象的计算遵循矩阵数学运算规律。矩阵使用 matrix 函数创建,以(2,2)大小的矩阵为例(2行2列),定义方法如下:

In [33]:
A = np.matrix([[1.0,2.0],[3.0,4.0]])
A
Out[33]:
matrix([[ 1.,  2.],
        [ 3.,  4.]])
In [34]:
# 查看A的类型
type(A)
Out[34]:
numpy.matrixlib.defmatrix.matrix

2.2 矩阵运算

矩阵的常用数学运算有转置、乘法、求逆等。下面的代码演示了矩阵的基本运算。

In [35]:
# 转置
A.T
Out[35]:
matrix([[ 1.,  3.],
        [ 2.,  4.]])
In [36]:
B = np.matrix([[3.0],[5.0]])
B
Out[36]:
matrix([[ 3.],
        [ 5.]])
In [37]:
# 矩阵乘法
A * B
Out[37]:
matrix([[ 13.],
        [ 29.]])
In [38]:
# 逆矩阵
A.I
Out[38]:
matrix([[-2. ,  1. ],
        [ 1.5, -0.5]])