master
/ 1Numpy 基础.ipynb

1Numpy 基础.ipynb @96fc089view markup · raw · history · blame

Notebook

Numpy 基础

在这节课中,我们将会学习到 Numpy 的相关内容。

NumPy(Numerical Python)是一个开源的 Python 科学计算库,用于快速处理任意维度的数组。

对于同样的数值计算任务,使用 NumPy 比直接使用 Python 要简洁的多。

ndarray 介绍

NumPy 提供了一个N 维数组类型 ndarray,它描述了相同类型items 的集合。

语文 数学 英语 政治 体育
80 89 86 67 79
78 97 89 76 81

ndarray 进行存储:

In [ ]:
import numpy as np

# 创建ndarray
score = np.array([[80, 89, 86, 67, 79],[78, 97, 89, 67, 81]])

# 打印结果
score

ndarray 的属性

数组属性反映了数组本身固有的信息。

属性名字 属性解释
ndarray.shape 数组维度的元组
ndarray.ndim 数组维数
ndarray.size 数组中的元素数量
ndarray.dtype 数组元素的类型
  • shape:数组形状
In [ ]:
import numpy as np

# 创建不同形状的数组
a = np.array([[1, 2, 3],[4, 5, 6]])
b = np.array([1, 2, 3, 4])
c = np.array([[[1, 2, 3],[4, 5, 6]],[[1, 2, 3],[4, 5, 6.0]]])

# 分别打印出形状
print(a.shape)
print(b.shape)
print(c.shape)
  • ndim:数组维数
In [ ]:
import numpy as np

# 创建不同形状的数组
a = np.array([[1, 2, 3],[4, 5, 6]])
b = np.array([1, 2, 3, 4])
c = np.array([[[1, 2, 3],[4, 5, 6]],[[1, 2, 3],[4, 5, 6.0]]])

# 分别打印出维数
print(a.ndim)
print(b.ndim)
print(c.ndim)
  • size:数组元素数量
In [ ]:
import numpy as np

# 创建不同形状的数组
a = np.array([[1, 2, 3],[4, 5, 6]])
b = np.array([1, 2, 3, 4])
c = np.array([[[1, 2, 3],[4, 5, 6]],[[1, 2, 3],[4, 5, 6.0]]])

# 分别打印出数组元素数量
print(a.size)
print(b.size)
print(c.size)
  • dtype:数组元素的类型
In [ ]:
import numpy as np

# 创建不同形状的数组
a = np.array([[1, 2, 3],[4, 5, 6]])
b = np.array([1, 2, 3, 4])
c = np.array([[[1, 2, 3],[4, 5, 6]],[[1, 2, 3],[4, 5, 6.0]]])

# 分别打印出数组元素数量
print(a.dtype)
print(b.dtype)
print(c.dtype)

编程练习

要求:把二维数组 [[1, 2, 3],[4, 5, 6],[7,8,9]] 转为 ndarray 格式。并查看其形状、维数和元素数量。

In [ ]:
# 请编写你的答案
In [ ]:
import numpy as np
a = np.array([[1, 2, 3],[4, 5, 6],[7, 8, 9]])
print(a)
print(a.shape)
print(a.ndim)
print(a.size)

ndarray 的类型

名称 描述
np.bool 用一个字节存储的布尔类型(True或False)
np.int8 一个字节大小,-128 至 127
np.int16 整数,-32768 至 32767
np.int32 整数,$-2^{31}$ 至 $2^{32} -1$
np.int64 整数,$-2^{63}$ 至 $2^{63} - 1$
np.uint8 无符号整数,0 至 255
np.uint16 无符号整数,0 至 65535
np.uint32 无符号整数,0 至 $2^{32} - 1$
np.uint64 无符号整数,0 至 $2^{64} - 1$
np.float16 半精度浮点数:16位,正负号1位,指数5位,精度10位
np.float32 单精度浮点数:32位,正负号1位,指数8位,精度23位
np.float64 双精度浮点数:64位,正负号1位,指数11位,精度52位
np.complex64 复数,分别用两个32位浮点数表示实部和虚部
np.complex128 复数,分别用两个64位浮点数表示实部和虚部
np.object_ python对象
np.string_ 字符串
np.unicode_ unicode类型

注意:创建数组的时候指定类型

In [ ]:
import numpy as np

# 创建数组时指定类型为 np.float32
a = np.array([[1, 2, 3],[4, 5, 6]], dtype=np.float32)

# 创建数组时未指定类型
b = np.array([[1, 2, 3],[4, 5, 6]])

# 打印结果
print("数组a:\n%s,\n数据类型:%s"%(a,a.dtype))
print("数组b:\n%s,\n数据类型:%s"%(b,b.dtype))

基本操作

生成元素值为 01 的数组的方法

  • 生成全部元素值为 0 的数组
In [ ]:
import numpy as np

zero = np.zeros([3, 4])
zero
  • 生成全部元素值为 1 的数组
In [ ]:
one = np.ones([3, 4])
one
  • 生成对角数组(对角线的地方是 1,其余地方是 0)
In [ ]:
eyes = np.eye(10, 5)
eyes
  • 创建方阵对角矩阵
In [ ]:
# np.eye(5, 5) 可简写为 (5)
eyes1 = np.eye(5)
eyes1

从现有数组生成

In [ ]:
a = [[1, 2, 3], [4, 5, 6]]

# 从现有的数组中创建
a1 = np.array(a)
a
In [ ]:
a1

生成固定范围的数组

In [ ]:
# 生成等间隔的数组
a = np.linspace(0, 90, 10)
a
In [ ]:
# 生成等间隔的数组
b = np.arange(0, 90, 10)
b

形状修改

In [ ]:
from numpy import array
a = array([[ 0, 1, 2, 3, 4, 5],
           [10,11,12,13,14,15],
           [20,21,22,23,24,25],
           [30,31,32,33,34,35]])
a.shape
In [ ]:
# 在转换形状的时候,一定要注意数组的元素匹配
# 只是将形状进行了修改,但并没有将行列进行转换
b = a.reshape([3, 8])
b
In [ ]:
# 数组的形状被修改为: (2, 12), -1: 表示同过自动计算得到此处的值
c = a.reshape([-1, 12])
c
In [ ]:
d = a.T
d.shape

类型修改

In [ ]:
arr = np.array([[[1, 2, 3], [4, 5, 6]], [[12, 3, 34], [5, 6, 7]]])
arr.dtype
In [ ]:
arr.astype(np.float32)

编程练习

要求:创建一个 3x3 并且值从0到8的矩阵

In [ ]:
# 请编写你的答案
In [ ]:
import numpy as np
Z = np.arange(9).reshape(3,3)
print(Z)

数组去重

In [ ]:
arr = np.array([[1, 2, 3, 4],[3, 4, 5, 6]])
np.unique(arr)

数组运算

数组的算术运算是元素级别的操作,新的数组被创建并且被结果填充。

运算 函数
a + b add(a,b)
a - b subtract(a,b)
a * b multiply(a,b)
a / b divide(a,b)
a ** b power(a,b)
a % b remainder(a,b)

以乘法为例,数组与标量相乘,相当于数组的每个元素乘以这个标量:

In [ ]:
import numpy as np
a = np.array([1, 2, 3, 4])
a * 3

数组按元素相乘:

In [ ]:
a = np.array([1, 2])
b = np.array([3, 4])
a * b

使用函数

In [ ]:
np.multiply(a, b)

函数还可以接受第三个参数,表示将结果存入第三个参数中:

In [ ]:
np.multiply(a, b, a)
In [ ]:
a

编程练习

要求:把二维数组 [[1, 2, 3],[4, 5, 6],[7,8,9]] 转为 ndarray 格式。并对每个元素 +1。

In [ ]:
# 请编写你的答案
In [ ]:
import numpy as np
a = np.array([[1, 2, 3],[4, 5, 6],[7, 8, 9]])
print(a+1)

矩阵

使用 mat 方法将 2 维数组转化为矩阵:

In [ ]:
import numpy as np
a = np.array([[1, 2, 4],
              [2, 5, 3],
              [7, 8, 9]])
A = np.mat(a)
A
In [ ]:
# 也可以使用 **Matlab** 的语法传入一个字符串来生成矩阵:
A = np.mat('1,2,4;2,5,3;7,8,9')
A

矩阵与向量的乘法:

In [ ]:
x = np.array([[1], [2], [3]])
x
In [ ]:
A*x
In [ ]:
b = np.array([[1, 2],
              [3, 4],
             [5, 6]])
B = np.mat(b)
A*B

A.I 表示 A 矩阵的逆矩阵:

In [ ]:
A.I

矩阵指数表示矩阵连乘:

In [ ]:
A ** 4

编程练习

要求:分别把二维数组 [[1, 2] ,[3, 4]] 和 [5, 6] ,[7, 8]]转为 matrix 格式。并计算矩阵的乘积。

In [ ]:
# 请编写你的答案
In [ ]:
import numpy as np
a = np.mat([[1, 2],[4, 5]])
b = np.mat([[5, 6],[7, 8]])
print(a*b)

统计函数

方法 作用
a.sum(axis=None) 求和
a.prod(axis=None) 求积
a.min(axis=None) 最小值
a.max(axis=None) 最大值
a.argmin(axis=None) 最小值索引
a.argmax(axis=None) 最大值索引
a.ptp(axis=None) 最大值减最小值
a.mean(axis=None) 平均值
a.std(axis=None) 标准差
a.var(axis=None) 方差
In [ ]:
from numpy import array
a = array([[1, 2, 3],
           [4, 5, 6]])
a

求所有元素的和:

In [ ]:
sum(a)
In [ ]:
a.sum()

指定求和的维度: 沿着第一维求和

In [ ]:
np.sum(a, axis=0)
In [ ]:
a.sum(axis=0)

沿着第二维求和:

In [ ]:
np.sum(a, axis=1)
In [ ]:
a.sum(axis=1)

沿着最后一维求和:

In [ ]:
np.sum(a, axis=-1)
In [ ]:
a.sum(axis=-1)

编程练习

要求:创建一个长度为30的随机向量并找到它的平均值

In [ ]:
# 请编写你的答案
In [ ]:
import numpy as np
Z = np.random.random(30)
m = Z.mean()
print(m)

比较和逻辑函数

运算符 函数
== equal
!= not_equal
> greater
>= greater_equal
< less
<= less_equal

数组元素的比对,我们可以直接使用运算符进行比较,比如判断数组中元素是否大于某个数:

In [ ]:
from numpy import array
a = array([[ 0, 1, 2, 3, 4, 5],
           [10,11,12,13,14,15],
           [20,21,22,23,24,25],
           [30,31,32,33,34,35]])

a > 10
In [ ]:
# 判断数组中元素大于10的元素赋值为 -10 
a[a > 10] = -10
a

但是当数组元素较多时,查看输出结果便变得很麻烦,这时我们可以使用all()方法,直接比对矩阵的所有对应的元素是否满足条件。假如判断某个区间的值是否全是大于 20:

In [ ]:
from numpy import array
a = array([[ 0, 1, 2, 3, 4, 5],
           [10,11,12,13,14,15],
           [20,21,22,23,24,25],
           [30,31,32,33,34,35]])

a[1:3,1:3]
In [ ]:
np.all(a[1:3,1:3] > 20)

使用 any() 来判断数组某个区间的元素是否存在大于 20的元素:

In [ ]:
np.any(a[1:3,1:3] > 20)

编程练习

要求:把二维数组 [[1, 2, 3],[4, 5, 6],[7,8,9]] 转为 ndarray 格式。判断是否全部大于 0。

In [ ]:
# 请编写你的答案
In [ ]:
import numpy as np
a = np.array([[1, 2, 3],[4, 5, 6],[7, 8, 9]])
print(np.all(a > 0))

IO 操作

savetxt 可以将数组写入文件,默认使用科学计数法的形式保存:

In [ ]:
import numpy as np

data = np.array([[1, 2],
                 [3, 4]])

# 保存文件
np.savetxt('out.txt', data)
In [ ]:
# 读取文件
with open('out.txt') as f:
    for line in f:
        print(line)
In [ ]:
# 读取文件
np.loadtxt('out.txt')