Numpy、Pandas、Matplotlib
Numpy (Pandas的内核是Numpy的) 。
有一个高维数组的数据类型,基于这种数组,我们可以做各种各样的数学运算,运算比python原生List类型更加简便。
Pandas , (数据的清洗,数据统计,数据的整合,.... 是python中的Excel)
Matplotlib,(基于Numpy的数据类型,画图的工具包)
Numpy 是什么
简单来说,Numpy 是Python 的一个科学计算包,包含了多维数组以及多维数组的操作。
Numpy 的核心是 ndarray 对象,这个对象封装了同质数据类型的n维数组。起名 ndarray 的原因就是因为是 n-dimension-array 的简写。
ndarray
Numpy 中最重要的一个对象就是 ndarray。
ndarray中的每个元素在内存中使用相同大小的块。 ndarray中的每个元素是数据类型对象的对象(称为 dtype)。
构建ndarray
从Python列表创建数组
import numpy as np
np.array(object, dtype=None)
object:转换的数据
dtype : 数据类型
np.array() 就相当于我们学习过的list,int,str等等,,将其他的数据类型转换为ndarray
# 和我们之前学习 list dict tuple 一个意思
# 将其他数据类型转换为 ndarray
L = [1,2,3]
t = (6,5,4)
n1 = np.array(L)
n1
array([1, 2, 3])
type(n1)
numpy.ndarray
L1 = [5,6,1]
ar1 = np.array(L1)
ar1
array([5, 6, 1])
L2 = [[2, 3], [4, 6, 8], [3, 5, 66]]
L2
[[2, 3], [4, 6, 8], [3, 5, 66]]
ar2 = np.array(L2)
ar2
array([list([2, 3]), list([4, 6, 8]), list([3, 5, 66])], dtype=object)
print(ar2)
[[ 2 3 5]
[ 4 6 8]
[ 3 5 66]]
ar2 = np.array(L2)
ar2
array([[ 2, 3, 5],
[ 4, 6, 8],
[ 3, 5, 66]])
type(ar1)
numpy.ndarray
L3 = ['N','u','m','p','y']
ar3 = np.array(L3)
ar3
array(['N', 'u', 'm', 'p', 'y'], dtype='
数据类型
Numpy 中的数组比 Python 原生中的数组(只支持整数类型与浮点类型)强大的一点就是它支持更多的数据类型。
基本数据类型
Numpy 常见的基本数据类型如下:
数据类型 | 描述 |
---|---|
bool_ | 布尔(True或False),存储为一个字节 |
int_ | 默认整数类型(与C long相同;通常为int64或int32) |
intc | 与C int(通常为int32或int64)相同 |
intp | 用于索引的整数(与C ssize_t相同;通常为int32或int64) |
int8 | 字节(-128到127) |
int16 | 整数(-32768到32767) |
int32 | 整数(-2147483648至2147483647) |
int64 | 整数(-9223372036854775808至9223372036854775807) |
uint8 | 无符号整数(0到255) |
uint16 | 无符号整数(0到65535) |
uint32 | 无符号整数(0至4294967295) |
uint64 | 无符号整数(0至18446744073709551615) |
float_ | float64的简写。 |
float16 | 半精度浮点:符号位,5位指数,10位尾数 |
float32 | 单精度浮点:符号位,8位指数,23位尾数 |
float64 | 双精度浮点:符号位,11位指数,52位尾数 |
object | Python对象,放什么都可以 |
234.55523433434
2**8
256
2**8 / 2
128.0
2 ** 16
65536
2 ** 16/2
32768.0
2 ** 32 / 2
2147483648.0
2 ** 64 / 2
9.223372036854776e+18
重点: ndarray里面只能装同一种数据类型
请记住,不同于 Python 列表,NumPy 要求数组必须包含同一类型的数据。如果类型不匹配,NumPy 将会向上转换(如果可行)。
下面让我们来看一下什么叫做向上转换.
这里整型被转换为浮点型:
L = [3,5,4.3]
np.array(L)
array([3. , 5. , 4.3])
L2 = [3,4.3, 'ab']
np.array(L2)
array(['3', '4.3', 'ab'], dtype='
b = np.array([3.14, 4, 2, 3])
b
array([3.14, 4. , 2. , 3. ])
b.dtype
dtype('float64')
np.array(['3',5,4.2])
array(['3', '5', '4.2'], dtype='
也可以强行指定类型, 则浮点型被转换成整型
a = np.array([3.14, 4, 2, 4], dtype='int64')
a
array([3, 4, 2, 4], dtype=int64)
a.dtype
dtype('int64')
类型转换
要转换数组的类型,请使用.astype()方法(首选)或类型本身作为函数。
** 指定数据类型,采用dtype参数 **
L = [3,5,4.3]
# dtype data type 数据类型
a = np.array(L, dtype = 'int64')
a
# 对于我的电脑, 整数型默认就是 64位, 但是对于 windows ,应该是32位
array([3, 5, 4])
L2 = [3, 3.3 , '3.56']
b = np.array(L2, dtype='float')
b
array([3. , 3.3 , 3.56])
# 查看一个数组的数据类型
b.dtype
dtype('float64')
# 改变已经生成的ndarray的数据类型
b.astype('str')
array(['3.0', '3.3', '3.56'], dtype='
b.astype('bool')
array([ True, True, True])
a = np.array([3.14, 4, 2, 4], dtype='int64')
a
array([3, 4, 2, 4], dtype=int64)
** 查看ndarray数据类型的方法: 用dtype **
a.dtype
dtype('int64')
** 转换数据类型的方法: 用astype **
a
array([3, 4, 2, 4], dtype=int64)
a.astype(np.bool_)
array([ True, True, True, True])
a.astype(np.float32)
array([3., 4., 2., 4.], dtype=float32)
a.astype('str')
array(['3', '4', '2', '4'], dtype='
ndarray 与 python 原生 array 有什么区别
NumPy 数组在创建时有固定的大小,不同于Python列表(可以动态增长)。更改ndarray的大小将创建一个新的数组并删除原始数据。
NumPy 数组中的元素都需要具有相同的数据类型,因此在存储器中将具有相同的大小。数组的元素如果也是数组(可以是 Python 的原生 array,也可以是 ndarray)的情况下,则构成了多维数组。
NumPy 数组便于对大量数据进行高级数学和其他类型的操作。通常,这样的操作比使用Python的内置序列可能更有效和更少的代码执行。
越来越多的科学和数学的基于Python的包使用NumPy数组,所以需要学会 Numpy 的使用。
Numpy 的矢量化(向量化)功能
如果想要将一个2-D数组 a 的每个元素与长度相同的另外一个数组 b 中相应位置的元素相乘,使用 Python 原生的数组实现如下:
a = [[1, 2, 3], [5, 7, 8], [4, 5, 6]]
b = [[6, 2, 1], [2, 3, 1], [4, 5, 6]]
a
[[1, 2, 3], [5, 7, 8], [4, 5, 6]]
b
[[6, 2, 1], [2, 3, 1], [4, 5, 6]]
# 两层循环,对二维数据进行遍历
for i in range(3):
for j in range(3):
print(a[i][j], b[i][j])
1 6
2 2
3 1
5 2
7 3
8 1
4 4
5 5
6 6
# 两层循环,对二维数据进行遍历
for i in range(3):
for j in range(3):
a[i][j]+ b[i][j]
Python基础小练习
写一段代码实现上述功能:
# 我们现根据列表的形状,创建一个空数组用于接收结果
c = [[0, 0, 0], [0, 0, 0], [0, 0, 0]]
# 两层循环,对二维数据进行遍历
for i in range(3):
for j in range(3):
c[i][j] = a[i][j]+ b[i][j]
c
[[7, 4, 4], [7, 10, 9], [8, 10, 12]]
# 我们现根据列表的形状,创建一个空数组用于接收结果
c = [[0, 0, 0], [0, 0, 0], [0, 0, 0]]
# 将对应位置的元素一次进行相加
for i in range(3):
for j in range(3):
c[i][j] = a[i][j]+b[i][j]
print(c) # 打印结果
[[7, 4, 4], [7, 10, 9], [8, 10, 12]]
在numpy中如何利用矢量化实现上述功能
a
[[1, 2, 3], [5, 7, 8], [4, 5, 6]]
b
[[6, 2, 1], [2, 3, 1], [4, 5, 6]]
# 将两个二维列表转换成 ndarray
a1 = np.array(a)
b1 = np.array(b)
a1
array([[1, 2, 3],
[5, 7, 8],
[4, 5, 6]])
b1
array([[6, 2, 1],
[2, 3, 1],
[4, 5, 6]])
# 直接相加,就是对应元素位置相加
a1 + b1
array([[ 7, 4, 4],
[ 7, 10, 9],
[ 8, 10, 12]])
a1 * 3
array([[ 3, 6, 9],
[15, 21, 24],
[12, 15, 18]])
a1 ** 2
array([[ 1, 4, 9],
[25, 49, 64],
[16, 25, 36]])
np.sqrt(a1)
array([[1. , 1.41421356, 1.73205081],
[2.23606798, 2.64575131, 2.82842712],
[2. , 2.23606798, 2.44948974]])
np.exp(a1)
array([[2.71828183e+00, 7.38905610e+00, 2.00855369e+01],
[1.48413159e+02, 1.09663316e+03, 2.98095799e+03],
[5.45981500e+01, 1.48413159e+02, 4.03428793e+02]])
a1 - b1
array([[-5, 0, 2],
[ 3, 4, 7],
[ 0, 0, 0]])
a1 + 1
array([[2, 3, 4],
[6, 8, 9],
[5, 6, 7]])
a1 * b1
array([[ 6, 4, 3],
[10, 21, 8],
[16, 25, 36]])
a1 = np.array(a)
b1 = np.array(b)
a1 + b1
array([[ 7, 4, 4],
[ 7, 10, 9],
[ 8, 10, 12]])
a1*b1
array([[ 6, 4, 3],
[10, 21, 8],
[16, 25, 36]])
a1 / b1
array([[0.16666667, 1. , 3. ],
[2.5 , 2.33333333, 8. ],
[1. , 1. , 1. ]])
a1
array([[1, 2, 3],
[5, 7, 8],
[4, 5, 6]])
a1 + 5
array([[ 6, 7, 8],
[10, 12, 13],
[ 9, 10, 11]])
a1 * 3
array([[ 3, 6, 9],
[15, 21, 24],
[12, 15, 18]])
a1 ** 2
array([[ 1, 4, 9],
[25, 49, 64],
[16, 25, 36]], dtype=int32)
矢量化代码有很多优点,其中包括:
- 矢量化代码更简洁易读
- 更少的代码行通常意味着更少的错误
- 该代码更接近地类似于标准数学符号(使得更容易,通常,以正确地编码数学构造)
- 矢量化导致更多的“Pythonic”代码。如果没有向量化,我们的代码将会效率很低,难以读取for循环。
小练习:
一家连锁店,A门店最近5天的营业额数据为: 1200,1398,2200,1100,1521
B门店5天营业额为: 1340,1211,1460,1121,1609
计算连锁店每天的总收入
计算连锁店5天的总收入
计算A店和B店的销售额的对数差
(不做)计算A店和B店每天销售量更高的是哪个店?
A = np.array([1200,1398,2200,1100,1521])
B = np.array([1340,1211,1460,1121,1609])
A
array([1200, 1398, 2200, 1100, 1521])
B
array([1340, 1211, 1460, 1121, 1609])
A + B
array([2540, 2609, 3660, 2221, 3130])
# 函数名称和math包一样的
np.sum(A+B)
14160
np.log(A) - np.log(B)
array([-0.11034806, 0.14359618, 0.41002092, -0.01891096, -0.05624485])
A - B
array([-140, 187, 740, -21, -88])
(A - B)>0
array([False, True, True, False, False])
创建常用的数组
单位矩阵,全零矩阵,三角矩阵等常用的矩阵数组,在线性代数的辅助计算中有很多特殊的作用
下面我们来看一下如何创建这些矩阵数组.
#全部行都能输出
from IPython.core.interactiveshell import InteractiveShell
InteractiveShell.ast_node_interactivity = "all"
a = 1
b = 2
a
b
1
2
创建一个全0数组
第一个参数输入数组的形状
# shape, 形状 ,数组的形状
# dtype=float,
np.zeros( 5 )
array([0., 0., 0., 0., 0.])
# 二维的
np.zeros( (3,2) )
array([[0., 0.],
[0., 0.],
[0., 0.]])
np.zeros((4,3), dtype= 'int')
array([[0, 0, 0],
[0, 0, 0],
[0, 0, 0],
[0, 0, 0]])
4 代表有几个二维平面构成三维体
3 每一个二维元素里面都是由三个一维元素构成的
2 每一个一维元素里面都是由2个0维元素构成的
# 三维数组
np.zeros((4,3,2), dtype= 'int')
array([[[0, 0],
[0, 0],
[0, 0]],
[[0, 0],
[0, 0],
[0, 0]],
[[0, 0],
[0, 0],
[0, 0]],
[[0, 0],
[0, 0],
[0, 0]]])
np.zeros((3, 5), dtype=int)
array([[0, 0, 0, 0, 0],
[0, 0, 0, 0, 0],
[0, 0, 0, 0, 0]])
np.zeros(10) # float型
np.zeros(10, dtype="int32")
np.zeros((3, 3), dtype="int32")
array([0., 0., 0., 0., 0., 0., 0., 0., 0., 0.])
array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0])
array([[0, 0, 0],
[0, 0, 0],
[0, 0, 0]])
全1数组
np.ones([4,3])
array([[1., 1., 1.],
[1., 1., 1.],
[1., 1., 1.],
[1., 1., 1.]])
np.ones(10) # float型
np.ones(10, dtype="int32")
np.ones((3, 3, 3), dtype="int32")
array([1., 1., 1., 1., 1., 1., 1., 1., 1., 1.])
array([1, 1, 1, 1, 1, 1, 1, 1, 1, 1], dtype=int32)
array([[[1, 1, 1],
[1, 1, 1],
[1, 1, 1]],
[[1, 1, 1],
[1, 1, 1],
[1, 1, 1]],
[[1, 1, 1],
[1, 1, 1],
[1, 1, 1]]], dtype=int32)
单位矩阵
np.eye(3)
array([[1., 0., 0.],
[0., 1., 0.],
[0., 0., 1.]])
np.eye(5)
array([[1., 0., 0., 0., 0.],
[0., 1., 0., 0., 0.],
[0., 0., 1., 0., 0.],
[0., 0., 0., 1., 0.],
[0., 0., 0., 0., 1.]])
np.eye(5,6)
array([[1., 0., 0., 0., 0., 0.],
[0., 1., 0., 0., 0., 0.],
[0., 0., 1., 0., 0., 0.],
[0., 0., 0., 1., 0., 0.],
[0., 0., 0., 0., 1., 0.]])
np.eye(6,5)
array([[1., 0., 0., 0., 0.],
[0., 1., 0., 0., 0.],
[0., 0., 1., 0., 0.],
[0., 0., 0., 1., 0.],
[0., 0., 0., 0., 1.],
[0., 0., 0., 0., 0.]])
# 向上偏移一行
np.eye(5, k = 1)
array([[0., 1., 0., 0., 0.],
[0., 0., 1., 0., 0.],
[0., 0., 0., 1., 0.],
[0., 0., 0., 0., 1.],
[0., 0., 0., 0., 0.]])
np.eye(5, k = -1)
array([[0., 0., 0., 0., 0.],
[1., 0., 0., 0., 0.],
[0., 1., 0., 0., 0.],
[0., 0., 1., 0., 0.],
[0., 0., 0., 1., 0.]])
np.eye(3, 3)
array([[1., 0., 0.],
[0., 1., 0.],
[0., 0., 1.]])
np.eye(3)
array([[1., 0., 0.],
[0., 1., 0.],
[0., 0., 1.]])
np.eye(3, dtype=int)
array([[1, 0, 0],
[0, 1, 0],
[0, 0, 1]])
对角矩阵
np.diag([1,2,3,4,5,6])
array([[1, 0, 0, 0, 0, 0],
[0, 2, 0, 0, 0, 0],
[0, 0, 3, 0, 0, 0],
[0, 0, 0, 4, 0, 0],
[0, 0, 0, 0, 5, 0],
[0, 0, 0, 0, 0, 6]])
np.diag([1,2,3,4,5,6], k = 1)
array([[0, 1, 0, 0, 0, 0, 0],
[0, 0, 2, 0, 0, 0, 0],
[0, 0, 0, 3, 0, 0, 0],
[0, 0, 0, 0, 4, 0, 0],
[0, 0, 0, 0, 0, 5, 0],
[0, 0, 0, 0, 0, 0, 6],
[0, 0, 0, 0, 0, 0, 0]])
np.diag([1, 5, 300, 444, 44, 666, 77])
array([[ 1, 0, 0, 0, 0, 0, 0],
[ 0, 5, 0, 0, 0, 0, 0],
[ 0, 0, 300, 0, 0, 0, 0],
[ 0, 0, 0, 444, 0, 0, 0],
[ 0, 0, 0, 0, 44, 0, 0],
[ 0, 0, 0, 0, 0, 666, 0],
[ 0, 0, 0, 0, 0, 0, 77]])
np.diag([1, 2, 3, 4, 5, 6, 7, 8, 'a'], 3)
array([['', '', '', '1', '', '', '', '', '', '', '', ''],
['', '', '', '', '2', '', '', '', '', '', '', ''],
['', '', '', '', '', '3', '', '', '', '', '', ''],
['', '', '', '', '', '', '4', '', '', '', '', ''],
['', '', '', '', '', '', '', '5', '', '', '', ''],
['', '', '', '', '', '', '', '', '6', '', '', ''],
['', '', '', '', '', '', '', '', '', '7', '', ''],
['', '', '', '', '', '', '', '', '', '', '8', ''],
['', '', '', '', '', '', '', '', '', '', '', 'a'],
['', '', '', '', '', '', '', '', '', '', '', ''],
['', '', '', '', '', '', '', '', '', '', '', ''],
['', '', '', '', '', '', '', '', '', '', '', '']], dtype='
d = np.diag(np.array([1, 2, 3, 4])) # 对角矩阵
d
array([[1, 0, 0, 0],
[0, 2, 0, 0],
[0, 0, 3, 0],
[0, 0, 0, 4]])
设定具体的值
np.full((4,3),666)
array([[666, 666, 666],
[666, 666, 666],
[666, 666, 666],
[666, 666, 666]])
np.full((3, 5),3.14 )
array([[ 3.14, 3.14, 3.14, 3.14, 3.14],
[ 3.14, 3.14, 3.14, 3.14, 3.14],
[ 3.14, 3.14, 3.14, 3.14, 3.14]])
np.full((2, 2), ((1, 2), (3, 4)))
array([[1, 2],
[3, 4]])
设置空值和无穷大
有一点要尤其注意的是: np.nan, np.inf 都是浮点类型
结合ndarray中的数据类型必须是相同的, 也就是说数组中如何有一个数据是空值,那么所有的数据都只能是浮点型.
np.nan
nan
type(np.nan)
# 如果数据中存在空值, 数据就是浮点型,不可能是整数型
float
np.inf
# infinity 无穷大
inf
type(np.inf)
float
np.nan
nan
np.nan?
np.inf
inf
随机数组
# size 和 shape一样, 就是形状,尺寸
np.random.randint(1,6,10) # 长度为10的一维数组
# 左闭右开区间
array([2, 1, 3, 5, 2, 1, 4, 3, 3, 3])
np.random.randint(1,6 , (3,4))
array([[1, 3, 5, 4],
[1, 5, 5, 3],
[5, 3, 5, 5]])
# 随机生成0-1之间的数字
np.random.rand(10)
array([0.37190143, 0.35734173, 0.32607687, 0.13083821, 0.76218832,
0.90225318, 0.37186817, 0.33367664, 0.65056737, 0.9526628 ])
# 多个维度之间拆开写 0 -1
np.random.rand(5,3)
array([[0.44904314, 0.17287316, 0.90866653],
[0.4969984 , 0.12808419, 0.40797815],
[0.92130526, 0.55951434, 0.28108364],
[0.35456297, 0.35293548, 0.74269503],
[0.53575099, 0.69653354, 0.72891147]])
# 和上面功能一样,但是参数不一样
np.random.random((5,3))
array([[0.7762202 , 0.44855912, 0.89922563],
[0.92296688, 0.94204828, 0.62716405],
[0.84601399, 0.45347043, 0.62994811],
[0.21051969, 0.63794732, 0.03446345],
[0.15669309, 0.04967971, 0.13949979]])
# 生成5 - 12 的一个随机序列:
# 首先将数据范围放大7倍, 然后向右平移5个单位
7 * np.random.rand(5,3) + 5
array([[ 5.27917046, 6.54114703, 8.58142788],
[ 7.52193583, 10.2189176 , 8.86585309],
[11.226403 , 7.19230501, 9.85323447],
[ 5.47913716, 11.2610729 , 10.89556392],
[ 9.46636357, 10.7116749 , 6.07128263]])
# 四舍五入到小数点后三位
np.round(np.random.random((5,3)) , 3)
array([[0.219, 0.763, 0.843],
[0.248, 0.99 , 0.049],
[0.421, 0.621, 0.088],
[0.494, 0.817, 0.196],
[0.287, 0.387, 0.492]])
np.random.randint(1, 10, (3, 6))
array([[5, 1, 8, 8, 9, 9],
[7, 7, 9, 5, 6, 5],
[6, 1, 5, 5, 5, 6]])
np.random.randint(4, 500,(4, 5) )
array([[420, 278, 194, 489, 316],
[368, 25, 235, 262, 229],
[163, 269, 336, 197, 411],
[329, 205, 337, 346, 159]])
np.random.randn(4, 5 )
array([[ 1.08195952, -0.53718982, -0.26884676, 0.19125376, 1.93979799],
[-0.20802373, 1.15151799, -0.30644614, 0.14496674, 1.71920808],
[-0.03412846, 1.08991245, 0.73255644, -1.7958478 , -1.69110694],
[-0.17930633, -1.76707642, 0.64034805, 0.38141222, -2.53867263]])
a = np.random.rand(2, 3) # uniform in [0, 1]
a
array([[0.05254766, 0.59756243, 0.99502083],
[0.4723183 , 0.72458214, 0.85551448]])
正态分布随机数
# 标准正太分布, 均值0 标准差 1
np.random.randn(10)
array([ 0.15358154, 0.49903574, 1.86139935, 0.47760835, 0.5901344 ,
-0.36477141, -0.59070377, -0.26886725, 0.97256738, 0.069651 ])
np.random.randn(4,3)
array([[-0.24107111, -0.67841998, 0.14501439],
[ 0.42535204, 0.21738205, 1.83561965],
[ 0.02205578, -0.60155464, 0.66631268],
[-0.92655788, -0.51934574, 0.10243237]])
# 均值为 5 , 标准差为3的正太分布
np.random.normal(5, 3, (3,4) )
array([[12.4958279 , 2.76909886, 6.85198811, 2.50947225],
[ 2.56366988, 3.85908711, 7.64035297, 3.47133109],
[ 7.2377767 , 6.94532057, 2.88185435, 4.71111279]])
array = np.random.normal(4, 2, (10, 3)) # 均值, 标准差, 形状
array
array([[ 5.95973621, 7.19262672, 2.98362756],
[ 4.78153143, 1.78440733, 5.8766825 ],
[ 5.43184024, 3.23992211, 3.71794129],
[ 5.20221566, 1.84128205, 1.94329058],
[ 2.75472565, 2.58743767, -3.26293124],
[ 4.50987806, 5.15885142, 1.11565559],
[ 2.19926954, 3.24967032, 0.22541738],
[ 3.37805791, 4.37907265, 2.40445887],
[ 6.53946577, 5.14046091, 5.23462548],
[ 1.0062933 , 2.51757328, 4.7654928 ]])
其他分布
# 卡方分布, 自由度5
np.random.chisquare(5, (3,4))
array([[6.99859872, 6.26238142, 1.01558914, 8.62465077],
[3.73866477, 8.81759966, 5.49948957, 5.33931607],
[4.18486524, 5.86505022, 4.80617685, 6.81408089]])
# t分布, 自由度3
np.random.standard_t(3, (3,4))
array([[ 1.86085286, -0.46657392, 0.39027598, -1.36164089],
[ 0.15906627, 2.78964462, 1.17377039, 1.20175289],
[ 0.7455645 , 2.96523855, -0.11373233, -0.10950068]])
# f分布
np.random.f(2,3,(3,4))
array([[0.59610158, 1.61507774, 0.58837518, 1.3066153 ],
[1.64393995, 0.1154248 , 0.09547755, 6.31918762],
[0.71516442, 4.07858266, 5.74033193, 0.50216236]])
# 泊松分布
np.random.poisson(0.5, (3,4))
array([[1, 1, 1, 0],
[0, 0, 1, 0],
[1, 0, 0, 1]])
# 二项分布
np.random.binomial(10, 0.5, (3,4))
array([[1, 3, 6, 7],
[4, 3, 5, 3],
[5, 5, 8, 3]])
设置随机数种子
np.random.seed(666)
# 二项分布
np.random.binomial(10, 0.5, (3,4))
array([[6, 7, 6, 6],
[8, 2, 5, 2],
[3, 5, 4, 6]])
np.random.seed(6666)
# 这个种子运行了之后, 马上运行的下一个随机数就是使用这个种子
np.random.randint(10)
1
# 二项分布
np.random.binomial(10, 0.5, (3,4))
array([[8, 5, 7, 6],
[3, 7, 4, 3],
[5, 4, 3, 2]])
np.random.randint(10)
4
# 设置随机数种子, 拆开发现不好使, 必须放在一起才好使
np.random.seed(200)
c = np.random.randn(2, 3)
c
创建一个线性序列的数组
np.arange(10)
# 如果只填一个 stop参数, 默认从0开始 ,步长是1
array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
np.arange(18)
# 如果只填一个 stop参数, 默认从0开始 ,步长是1
array([ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
17])
np.arange(10,18)
array([10, 11, 12, 13, 14, 15, 16, 17])
np.arange(1,20,3)
array([ 1, 4, 7, 10, 13, 16, 19])
# 步长为负的
np.arange(10, 2, -1)
array([10, 9, 8, 7, 6, 5, 4, 3])
# 可以是小数
np.arange(0.1, 1, 0.1)
array([0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9])
np.arange(20 , 1 , -0.2)
array([20. , 19.8, 19.6, 19.4, 19.2, 19. , 18.8, 18.6, 18.4, 18.2, 18. ,
17.8, 17.6, 17.4, 17.2, 17. , 16.8, 16.6, 16.4, 16.2, 16. , 15.8,
15.6, 15.4, 15.2, 15. , 14.8, 14.6, 14.4, 14.2, 14. , 13.8, 13.6,
13.4, 13.2, 13. , 12.8, 12.6, 12.4, 12.2, 12. , 11.8, 11.6, 11.4,
11.2, 11. , 10.8, 10.6, 10.4, 10.2, 10. , 9.8, 9.6, 9.4, 9.2,
9. , 8.8, 8.6, 8.4, 8.2, 8. , 7.8, 7.6, 7.4, 7.2, 7. ,
6.8, 6.6, 6.4, 6.2, 6. , 5.8, 5.6, 5.4, 5.2, 5. , 4.8,
4.6, 4.4, 4.2, 4. , 3.8, 3.6, 3.4, 3.2, 3. , 2.8, 2.6,
2.4, 2.2, 2. , 1.8, 1.6, 1.4, 1.2])
arange([start,] stop[, step,])
特点: 可以设置开始位置,终止位置和步长,但产生数字的数量不方便控制
np.arange(0, 20, 2)
np.arange(20)
np.arange(0, 20, 4)
array([ 0, 4, 8, 12, 16])
# 想要生成 1 - 20 为区间的 38个数
np.linspace(开始位置, 终止位置, 产生数量)
特点: 可以设置开始位置和终止位置以及产生数量,但不方便控制步长
# 想要生成 1 - 20 为区间的 38个数
np.linspace(1,20 , 38)
array([ 1. , 1.51351351, 2.02702703, 2.54054054, 3.05405405,
3.56756757, 4.08108108, 4.59459459, 5.10810811, 5.62162162,
6.13513514, 6.64864865, 7.16216216, 7.67567568, 8.18918919,
8.7027027 , 9.21621622, 9.72972973, 10.24324324, 10.75675676,
11.27027027, 11.78378378, 12.2972973 , 12.81081081, 13.32432432,
13.83783784, 14.35135135, 14.86486486, 15.37837838, 15.89189189,
16.40540541, 16.91891892, 17.43243243, 17.94594595, 18.45945946,
18.97297297, 19.48648649, 20. ])
np.linspace(1,20 , 38,endpoint=False)
# 左闭右开
array([ 1. , 1.5, 2. , 2.5, 3. , 3.5, 4. , 4.5, 5. , 5.5, 6. ,
6.5, 7. , 7.5, 8. , 8.5, 9. , 9.5, 10. , 10.5, 11. , 11.5,
12. , 12.5, 13. , 13.5, 14. , 14.5, 15. , 15.5, 16. , 16.5, 17. ,
17.5, 18. , 18.5, 19. , 19.5])
np.linspace(1,20 , 38,retstep=True)
# retstep 步长也返回回来
(array([ 1. , 1.51351351, 2.02702703, 2.54054054, 3.05405405,
3.56756757, 4.08108108, 4.59459459, 5.10810811, 5.62162162,
6.13513514, 6.64864865, 7.16216216, 7.67567568, 8.18918919,
8.7027027 , 9.21621622, 9.72972973, 10.24324324, 10.75675676,
11.27027027, 11.78378378, 12.2972973 , 12.81081081, 13.32432432,
13.83783784, 14.35135135, 14.86486486, 15.37837838, 15.89189189,
16.40540541, 16.91891892, 17.43243243, 17.94594595, 18.45945946,
18.97297297, 19.48648649, 20. ]), 0.5135135135135135)
np.linspace(1, 101, 49, dtype=int)
array([ 1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 26,
28, 30, 32, 34, 36, 38, 40, 42, 44, 46, 48, 51, 53,
55, 57, 59, 61, 63, 65, 67, 69, 71, 73, 76, 78, 80,
82, 84, 86, 88, 90, 92, 94, 96, 98, 101])
np.linspace(1, 2, 3, endpoint=False)
array([1. , 1.33333333, 1.66666667])
# 创建一个5个元素的数组, 5个数均匀的分配到我们设置的空间内
np.linspace(0, 5, 6, dtype="int32")
np.linspace(0, 1, 8)
array([0. , 0.14285714, 0.28571429, 0.42857143, 0.57142857,
0.71428571, 0.85714286, 1. ])
小练习:
生成一个6行6列的单位矩阵数组,数据类型为字符串
生成一个(2,3,4)的数组,并使用无穷大进行填充
生成5,15的随机整数数组,形状为(3,6)
生成3行4列的标准正态分布数组
生成均值为10,标准差为5的(7,3)的正太分布
生成从12到22,步长为2的序列
生成从12到22的序列,序列的长度为100个
np.eye(6,dtype='str') # U Unicode编码 , 1 个字节
array([['1', '', '', '', '', ''],
['', '1', '', '', '', ''],
['', '', '1', '', '', ''],
['', '', '', '1', '', ''],
['', '', '', '', '1', ''],
['', '', '', '', '', '1']], dtype='
np.full((2,3,4),np.inf)
array([[[inf, inf, inf, inf],
[inf, inf, inf, inf],
[inf, inf, inf, inf]],
[[inf, inf, inf, inf],
[inf, inf, inf, inf],
[inf, inf, inf, inf]]])
np.random.randint(5,15,(3,6))
array([[ 7, 7, 10, 8, 5, 11],
[ 7, 12, 5, 12, 13, 10],
[ 6, 5, 13, 13, 12, 11]])
np.random.randn(3,4)
array([[ 0.8496988 , 0.63345123, -1.65804727, 0.66434895],
[ 0.77047956, -0.53521953, -0.09216605, -0.81679028],
[ 0.98872162, 1.58782622, -0.07154457, -0.32017843]])
np.random.normal(10,5, (7,3))
array([[16.59458962, 10.42403408, 8.16620932],
[11.18451949, 14.20542267, 16.55842567],
[12.99896942, 10.87580929, 4.75328254],
[-0.0304916 , 13.63382418, 6.68611022],
[10.83014024, 6.53755179, 13.97874697],
[ 9.38185163, 13.02309531, 9.11597071],
[ 6.70235872, 21.41385018, 14.22344329]])
np.arange(12,22,2)
array([12, 14, 16, 18, 20])
np.linspace(12,22,100)
array([12. , 12.1010101 , 12.2020202 , 12.3030303 , 12.4040404 ,
12.50505051, 12.60606061, 12.70707071, 12.80808081, 12.90909091,
13.01010101, 13.11111111, 13.21212121, 13.31313131, 13.41414141,
13.51515152, 13.61616162, 13.71717172, 13.81818182, 13.91919192,
14.02020202, 14.12121212, 14.22222222, 14.32323232, 14.42424242,
14.52525253, 14.62626263, 14.72727273, 14.82828283, 14.92929293,
15.03030303, 15.13131313, 15.23232323, 15.33333333, 15.43434343,
15.53535354, 15.63636364, 15.73737374, 15.83838384, 15.93939394,
16.04040404, 16.14141414, 16.24242424, 16.34343434, 16.44444444,
16.54545455, 16.64646465, 16.74747475, 16.84848485, 16.94949495,
17.05050505, 17.15151515, 17.25252525, 17.35353535, 17.45454545,
17.55555556, 17.65656566, 17.75757576, 17.85858586, 17.95959596,
18.06060606, 18.16161616, 18.26262626, 18.36363636, 18.46464646,
18.56565657, 18.66666667, 18.76767677, 18.86868687, 18.96969697,
19.07070707, 19.17171717, 19.27272727, 19.37373737, 19.47474747,
19.57575758, 19.67676768, 19.77777778, 19.87878788, 19.97979798,
20.08080808, 20.18181818, 20.28282828, 20.38383838, 20.48484848,
20.58585859, 20.68686869, 20.78787879, 20.88888889, 20.98989899,
21.09090909, 21.19191919, 21.29292929, 21.39393939, 21.49494949,
21.5959596 , 21.6969697 , 21.7979798 , 21.8989899 , 22. ])
ndarray常用属性
数组的属性
现在我们定义三个数组, 一维数组, 二维数组, 三维数组
# 先设置随机数种子
np.random.seed(0)
x1 = np.random.randint(10, size=6) # 一维数组
x2 = np.random.randint(10, size=(3, 4)) # 二维数组
x3 = np.random.randint(10, size=(3, 4, 5)) # 三维数组
array([[5, 0, 3, 3],
[7, 9, 3, 5],
[2, 4, 7, 6]])
x1
x2
x3
array([5, 0, 3, 3, 7, 9])
array([[3, 5, 2, 4],
[7, 6, 8, 8],
[1, 6, 7, 7]])
array([[[8, 1, 5, 9, 8],
[9, 4, 3, 0, 3],
[5, 0, 2, 3, 8],
[1, 3, 3, 3, 7]],
[[0, 1, 9, 9, 0],
[4, 7, 3, 2, 7],
[2, 0, 0, 4, 5],
[5, 6, 8, 4, 1]],
[[4, 9, 8, 1, 1],
[7, 9, 9, 3, 6],
[7, 2, 0, 3, 5],
[9, 4, 4, 6, 4]]])
查看数据形状
x1.shape
x2.shape
x3.shape
(6,)
(3, 4)
(3, 4, 5)
查看维度
想要查看数组的维度
x1.ndim
x2.ndim
x3.ndim
1
2
3
查看数组元素个数
x1.size
x2.size
x3.size
6
12
60
x1.dtype
x2.dtype
x3.dtype
dtype('int64')
dtype('int64')
dtype('int64')
数组的索引和切片
Python 中原生的数组就支持使用方括号([])进行索引和切片操作,Numpy 也同样具有这个强大的特性。
单个元素索引
1-D数组的单元素索引是人们期望的。它的工作原理与其他标准Python序列一样。它是从0开始的,并且接受负索引来从数组的结尾进行索引。
x = np.arange(10)
x
array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
x[2:5]
array([2, 3, 4])
x[-1]
9
x[::2]
array([0, 2, 4, 6, 8])
高维数组索引
与Python原生的列表、元组不同的是,Numpy数组支持多维数组的多维索引。
每一个逗号, 代表索引的一个维度
x2
array([[3, 5, 2, 4],
[7, 6, 8, 8],
[1, 6, 7, 7]])
# 练习:
# 7 6
1 6
# 3 5 2
7 6 8
1 6 7
# 3, 4
7 8
x2[1: , :2]
array([[7, 6],
[1, 6]])
x2[ : ,:3]
array([[3, 5, 2],
[7, 6, 8],
[1, 6, 7]])
x2[:2 , ::3]
array([[3, 4],
[7, 8]])
x2[ :2 , 1::2]
array([[5, 4],
[6, 8]])
# 原来的这种语法有很强的局限性
x2[1][1]
6
x2[1][:2]
array([7, 6])
x2[ 第一个维度 , 第二个维度 ]
x2[ 行 , 列 ]
x2[1, 1] # 第一行,第一列
6
x2[:2 ,2 ]
array([2, 8])
# 切除左上角四个元素
x2[:2 , :2]
array([[3, 5],
[7, 6]])
x2[1:, 1:3]
array([[6, 8],
[6, 7]])
x2[0]
x2[0, 0]
x2[1, 1]
array([3, 5, 2, 4])
3
6
x3[0]
x3[0, 0]
array([8, 1, 5, 9, 8])
修改某一个元素值
x2
array([[3, 5, 2, 4],
[7, 6, 8, 8],
[1, 6, 7, 7]])
# 修改一个
x2[-1,-1] = 700
x2
array([[ 3, 5, 2, 4],
[ 7, 6, 8, 8],
[ 1, 6, 7, 700]])
x2[:2,:2] = 100
x2 # 左上角四个都改成100
array([[100, 100, 2, 4],
[100, 100, 8, 8],
[ 1, 6, 7, 700]])
x2[:2, -1] *= 100 # 原来基础上乘100
x2
array([[100, 100, 2, 400],
[100, 100, 8, 800],
[ 1, 6, 7, 700]])
x1
x1[0] = 1999
x1[1] = 3.1415926 # 类型会自动转换
x1
array([1999, 3, 3, 3, 7, 9])
切片
可以使用切片和步长来截取不同长度的数组,使用方式与Python原生的对列表和元组的方式相同。
语法和列表的切片是一样的
x[start:stop:step]
x2
array([[3, 5, 2, 4],
[7, 6, 8, 8],
[1, 6, 7, 7]])
#x2[第一维度,第二维度 ]
x2[:2:1, 0:2:1]
array([[3, 5],
[7, 6]])
x2[0:2,1:3 ]
array([[5, 2],
[6, 8]])
#获取第1列
x2[:, 1]
array([5, 6, 6])
关于视图
# 为了确保大家都能生成一样的数组, 我们先设置随机数种子
np.random.seed(0)
x2 = np.random.randint(10, size=(3, 4)) # 二维数组
x2
array([[5, 0, 3, 3],
[7, 9, 3, 5],
[2, 4, 7, 6]])
关于数组切片有一点很重要也非常有用,那就是数组切片返回的是
数组数据的视图,而不是数值数据的副本。这一点也是 NumPy 数
组切片和 Python 列表切片的不同之处:在 Python 列表中,切片是
值的副本。例如此前示例中的那个二维数组:
x2
array([[5, 0, 3, 3],
[7, 9, 3, 5],
[2, 4, 7, 6]])
# 切左上角的四个元素
x2_0 = x2[:2,:2]
x2_0
array([[5, 0],
[7, 9]])
# 对x2_0 中的数据进行修改
x2_0[0,0] = 500
x2_0
array([[500, 0],
[ 7, 9]])
# x2 上面的数据,也同步发生了变化
x2
array([[500, 0, 3, 3],
[ 7, 9, 3, 5],
[ 2, 4, 7, 6]])
x2_0 = x2[:2, :2]
x2_0
array([[3, 5],
[7, 6]])
x2_0[0, 0] = 8888
x2_0
array([[8888, 5],
[ 7, 6]])
x2
array([[8888, 5, 2, 4],
[ 7, 6, 8, 8],
[ 1, 6, 7, 7]])
改为创建副本
也可以通过.copy()方法创建一个副本
# 为了确保大家都能生成一样的数组, 我们先设置随机数种子
np.random.seed(0)
x2 = np.random.randint(10, size=(3, 4)) # 二维数组
x2
array([[5, 0, 3, 3],
[7, 9, 3, 5],
[2, 4, 7, 6]])
x2_1 = x2[:2,:2].copy()# 副本(深复制)
x2_1
array([[5, 0],
[7, 9]])
x2_1[0,0] = 500
x2_1
array([[500, 0],
[ 7, 9]])
x2
array([[5, 0, 3, 3],
[7, 9, 3, 5],
[2, 4, 7, 6]])
x2_1 = x2[:2, :2].copy()
x2_1
array([[4, 3],
[8, 4]])
x2_1[0, 0] = 8888
x2_1
array([[8888, 3],
[ 8, 4]])
x2
array([[4, 3, 4, 4],
[8, 4, 3, 7],
[5, 5, 0, 1]])
复制和视图
完全不复制
简单赋值不会创建数组对象或其数据的拷贝。
使用这种方式复制,两个变量并没有区别,改变一个另外一个会同步变化
a = np.arange(6)
a
array([0, 1, 2, 3, 4, 5])
b = a
id(a)
4646325824
id(b)
4646325824
a[0] = 100
a
array([100, 1, 2, 3, 4, 5])
b
array([100, 1, 2, 3, 4, 5])
a = np.arange(6)
a
b = a #
id(a)
id(b) # id(a)和id(b)结果相同
b.shape = 3,2
a.shape # 修改b形状,结果a的形状也变了
array([0, 1, 2, 3, 4, 5])
2070479453280
2070479453280
(3, 2)
视图或浅复制
不同的数组对象可以共享相同的数据。view方法创建一个新数组对象,该对象看到相同的数据。与前一种情况不同,新数组的维数更改不会更改原始数据的维数,但是新数组数据更改后,也会影响原始数据。
a = np.arange(0, 12, 1).reshape(6, 2)
a
array([[ 0, 1],
[ 2, 3],
[ 4, 5],
[ 6, 7],
[ 8, 9],
[10, 11]])
c = a.view()
c
array([[ 0, 1],
[ 2, 3],
[ 4, 5],
[ 6, 7],
[ 8, 9],
[10, 11]])
c[0,0] = 100
c
array([[100, 1],
[ 2, 3],
[ 4, 5],
[ 6, 7],
[ 8, 9],
[ 10, 11]])
a
array([[100, 1],
[ 2, 3],
[ 4, 5],
[ 6, 7],
[ 8, 9],
[ 10, 11]])
# 对shape属性 重新赋值
c.shape = 3,4
c
array([[100, 1, 2, 3],
[ 4, 5, 6, 7],
[ 8, 9, 10, 11]])
a
array([[100, 1],
[ 2, 3],
[ 4, 5],
[ 6, 7],
[ 8, 9],
[ 10, 11]])
a[0,1] = 200
a
array([[100, 200],
[ 2, 3],
[ 4, 5],
[ 6, 7],
[ 8, 9],
[ 10, 11]])
c
array([[100, 200, 2, 3],
[ 4, 5, 6, 7],
[ 8, 9, 10, 11]])
c = a.view()
c
array([[ 0, 1],
[ 2, 3],
[ 4, 5],
[ 6, 7],
[ 8, 9],
[10, 11]])
c.shape = 2,6
c
array([[ 0, 1, 2, 3, 4, 5],
[ 6, 7, 8, 9, 10, 11]])
a.shape
(6, 2)
c[0,4] = 1234
a
array([[ 0, 1],
[ 2, 3],
[1234, 5],
[ 6, 7],
[ 8, 9],
[ 10, 11]])
深复制
完全复制了一个新的,两个数组之间不在有任何关联
d = a.copy() # 一个完整的新的数组
d
array([[100, 200],
[ 2, 3],
[ 4, 5],
[ 6, 7],
[ 8, 9],
[ 10, 11]])
a
array([[100, 200],
[ 2, 3],
[ 4, 5],
[ 6, 7],
[ 8, 9],
[ 10, 11]])
d[0,0] = 9999
d
array([[9999, 200],
[ 2, 3],
[ 4, 5],
[ 6, 7],
[ 8, 9],
[ 10, 11]])
a # 修改数组 d 的值,a不会受影响
array([[100, 200],
[ 2, 3],
[ 4, 5],
[ 6, 7],
[ 8, 9],
[ 10, 11]])
小练习:
创建一个随机数组,数组分布在0-1之间,形状为(5,7)
把其中的第一列数据中的第2,3个,第二列的第1,5个设置为空
输出数组的形状,数据类型,元素个数
把右下角的数字改为0.38
把最右排数字统一加上0.25
整个数组统一乘以3
x = np.random.rand(5,7)
x
array([[0.35944446, 0.48089353, 0.68866118, 0.88047589, 0.91823547,
0.21682214, 0.56518887],
[0.86510256, 0.50896896, 0.91672295, 0.92115761, 0.08311249,
0.27771856, 0.0093567 ],
[0.84234208, 0.64717414, 0.84138612, 0.26473016, 0.39782075,
0.55282148, 0.16494046],
[0.36980809, 0.14644176, 0.56961841, 0.70373728, 0.28847644,
0.43328806, 0.75610669],
[0.39609828, 0.89603839, 0.63892108, 0.89155444, 0.68005557,
0.44919774, 0.97857093]])
x[0, 2:4]= np.nan
x[1 , 1:6:4 ] = np.nan
x
array([[0.35944446, 0.48089353, nan, nan, 0.91823547,
0.21682214, 0.56518887],
[0.86510256, nan, 0.91672295, 0.92115761, 0.08311249,
nan, 0.0093567 ],
[0.84234208, 0.64717414, 0.84138612, 0.26473016, 0.39782075,
0.55282148, 0.16494046],
[0.36980809, 0.14644176, 0.56961841, 0.70373728, 0.28847644,
0.43328806, 0.75610669],
[0.39609828, 0.89603839, 0.63892108, 0.89155444, 0.68005557,
0.44919774, 0.97857093]])
x.shape
(5, 7)
x.dtype
dtype('float64')
x.size
35
x[-1,-1] = 0.38
x
array([[0.35944446, 0.48089353, nan, nan, 0.91823547,
0.21682214, 0.56518887],
[0.86510256, nan, 0.91672295, 0.92115761, 0.08311249,
nan, 0.0093567 ],
[0.84234208, 0.64717414, 0.84138612, 0.26473016, 0.39782075,
0.55282148, 0.16494046],
[0.36980809, 0.14644176, 0.56961841, 0.70373728, 0.28847644,
0.43328806, 0.75610669],
[0.39609828, 0.89603839, 0.63892108, 0.89155444, 0.68005557,
0.44919774, 0.38 ]])
x[:, -1] += 0.25
x
array([[0.35944446, 0.48089353, nan, nan, 0.91823547,
0.21682214, 0.81518887],
[0.86510256, nan, 0.91672295, 0.92115761, 0.08311249,
nan, 0.2593567 ],
[0.84234208, 0.64717414, 0.84138612, 0.26473016, 0.39782075,
0.55282148, 0.41494046],
[0.36980809, 0.14644176, 0.56961841, 0.70373728, 0.28847644,
0.43328806, 1.00610669],
[0.39609828, 0.89603839, 0.63892108, 0.89155444, 0.68005557,
0.44919774, 0.63 ]])
x *= 3
x
array([[1.07833339, 1.44268059, nan, nan, 2.7547064 ,
0.65046641, 2.4455666 ],
[2.59530768, nan, 2.75016886, 2.76347283, 0.24933748,
nan, 0.77807011],
[2.52702624, 1.94152242, 2.52415836, 0.79419049, 1.19346226,
1.65846444, 1.24482138],
[1.10942428, 0.43932529, 1.70885522, 2.11121184, 0.86542931,
1.29986419, 3.01832008],
[1.18829483, 2.68811516, 1.91676323, 2.67466331, 2.04016671,
1.34759321, 1.89 ]])