incipe
读完需要
20分钟速读仅需 7 分钟
什么是 Numpy
❝NumPy 是一个运行速度非常快的数学库,主要用于数组计算,包含:
❞
- 一个强大的 N 维数组对象 ndarray
- 广播功能函数
- 整合 C/C++/Fortran 代码的工具
- 线性代数、傅里叶变换、随机数生成等功能
使用
Ⅰ. 创建 ndarray
调用 array()
方法即可。
def array(object, dtype=None, copy=True, order='K', subok=False, ndmin=0)
参数:
object
数组或嵌套的数列。dtype
数组元素的数据类型。copy
对象是否需要复制。order
创建数组的样式,,C 为行方向,F 为列方向,A 原顺序,K 元素在内存中的出现顺序。subok
默认返回一个与基类类型一致的数组。ndmin
指定生成数组的最小维度。
还可以使用:
numpy.arange(12) # 创建一个一维数组。
`# array([ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11])`
numpy.arange(12).reshape(3, 4) # 创建一个3行4列的数组。
"""
array([[ 0, 1, 2, 3],
[ 4, 5, 6, 7],
[ 8, 9, 10, 11]])
"""
numpy.arange(12).reshape(2, 2, 3) # 创建一个三维数组
"""
array([[[ 0, 1, 2],
[ 3, 4, 5]],
[[ 6, 7, 8],
[ 9, 10, 11]]])
"""
怎么理解三维数组,简单的来说,我们把第一维看成数组分成了多少块,第二维就是每块有机房,第三维就是有几列。
Ⅱ. 查看数据类型
调用方法 dtype
即可。
t1 = np.arange(18).reshape(3, 3, 2)
t1.detype
"""
dtype('int64')
"""
更多数据类型请参考 numpy 中文网[1]
Ⅲ. 查看数组维度
调用 shape
方法即可。
import numpy as np
t1 = np.array([[1, 2, 3], [4, 5, 6]])
t1.shape
# (2, 3)
shape
方法给我们返回一个元组。
调用 reshape()
方法改变数组形状。
t2 = t1.reshape(3, 2)
"""
array([[1, 2],
[3, 4],
[5, 6]])
"""
调用 reshape()
方法后,原来的数组形状是不变的,返回值返回变形后的新数组。
把数组转化为一维数组。
t3 = t2.flatten()
"""
array([1, 2, 3, 4, 5, 6])
"""
还可以用
t4 = t2.reshape(6,)
"""
array([1, 2, 3, 4, 5, 6])
"""
或者
t5 = t2.reshape(t2.shape[0] * t2.shape[1], )
"""
array([1, 2, 3, 4, 5, 6])
"""
因为 shape
方法返回一个 tuple
所以第一个是行,第二个是列,行 × 列就是数组总个数。
转换成二维,三维方法一样 t.reshape(2, 3)
把数组 t
转化为 2 行 3 列的数组。
Ⅳ. 数组的计算
数组与数字
数字和数组里面的每个数字相加、相减、相乘、相除。
t = np.array([[[1, 2, 3], [4, 5, 6], [7, 8, 9]]])
t += 2
"""
array([[[ 3, 4, 5],
[ 6, 7, 8],
[ 9, 10, 11]]])
"""
注意,这里除 0,只会有警告,不会报错。
t = np.array([0, 1, 2])
t /= 0
# array([nan, inf, inf])
这里的 nan
是由 0 除 0 产生的,即 not a number
不是一个数字
这里的 inf
是由其它数字除 0 产生的,即 无穷的意思。
数组与数组
- 当数组形状一样的时候,加减乘除都是对应位置的元素进行计算。
t1 = np.arange(12).reshape(3, 4)
t2 = np.arange(100, 112).reshape(3, 4)
t1 + t2
"""
array([[100, 102, 104, 106],
[108, 110, 112, 114],
[116, 118, 120, 122]])
"""
数组形状不一样时,如果两个数组的后缘维度(从后面开始算起的维度)的轴长度相符或其中一方长度为 1 时,是广播相容的。
比如,(3, 4)和 (4,)是可以计算的;(2, 3, 4)和(1, 3, 4)是可以计算的。
t1 = np.arange(12).reshape(3, 4)
"""
array([[ 0, 1, 2, 3],
[ 4, 5, 6, 7],
[ 8, 9, 10, 11]])
"""
t3 = np.arange(4)
# array([0, 1, 2, 3])
t1 + t3
"""
array([[ 0, 2, 4, 6],
[ 4, 6, 8, 10],
[ 8, 10, 12, 14]])
"""
或者
t1 = np.arange(12).reshape(3, 4)
"""
array([[ 0, 1, 2, 3],
[ 4, 5, 6, 7],
[ 8, 9, 10, 11]])
"""
t4 = np.arange(3).reshape(3, 1)
"""
array([[0],
[1],
[2]])
"""
t1 + t4
"""
array([[ 0, 1, 2, 3],
[ 5, 6, 7, 8],
[10, 11, 12, 13]])
"""
Ⅴ. 读取数据
这个功能用的不多,因为 pandas
太强了。
import numpy as np
np.loadtxt(frame, dtype=float, comments='#', delimiter=None, converters=None, skiprows=0, usecols=None, unpack=False, ndmin=0, encoding='bytes', max_rows=None)
参数:
frame
文件,字符串或者产生器,一般是文件的绝对路径或者相对路径。dtype
数据类型、文件的字符串以什么数据类型读入数组中。comments
跳过文件中指定参数开头的行。delimiter
读取文件中数据的分隔符。converters
对读取的数据进行预处理。skiprows
选择跳过的行数,一般跳过第一行表头。uescols
指定需要读取的列。unpack
如果为 True,读入属性将分别写入不同数组变量,False 读入数据只写入一个数组变量。就是转置的意思。encoding
对读取文件进行预编码。max_rows
最大读取行数。
Ⅵ. 数组的转置
一维数组不需要转置。
二维数组转置
import numpy as np
t1 = np.arange(24).reshape(4, 6)
t2 = t1.T
"""
array([[ 0, 6, 12, 18],
[ 1, 7, 13, 19],
[ 2, 8, 14, 20],
[ 3, 9, 15, 21],
[ 4, 10, 16, 22],
[ 5, 11, 17, 23]])
"""
t3 = t1.transpose()
"""
array([[ 0, 6, 12, 18],
[ 1, 7, 13, 19],
[ 2, 8, 14, 20],
[ 3, 9, 15, 21],
[ 4, 10, 16, 22],
[ 5, 11, 17, 23]])
"""
三维及三维以上。
t4 = np.arange(16).reshape(2, 2, 4)
t4.transpose((1, 0, 2))
"""
array([[[ 0, 1, 2, 3],
[ 8, 9, 10, 11]],
[[ 4, 5, 6, 7],
[12, 13, 14, 15]]])
"""
t4.swapaxes(1, 0)
"""
array([[[ 0, 1, 2, 3],
[ 8, 9, 10, 11]],
[[ 4, 5, 6, 7],
[12, 13, 14, 15]]])
"""
transpose()
接受一个元组,原来的轴是 (0, 1, 2)
通过 transpose()
方法把原来的 0
轴变成了 1
轴。
三维的数组的轴,就看成一个 xyz
坐标系即可。x
轴对应于 0
轴,y
轴对应于 1
轴,z
轴对应于 2
轴。
Ⅶ. numpy 索引和切片
取行
import numpy as np
t = np.arange(24).reshape(4, 6)
"""
array([[ 0, 1, 2, 3, 4, 5],
[ 6, 7, 8, 9, 10, 11],
[12, 13, 14, 15, 16, 17],
[18, 19, 20, 21, 22, 23]])
"""
t[1] # t[1, :]
"""
array([0, 1, 2, 3, 4, 5])
"""
t[1::] # t[1::, :]
"""
array([[ 6, 7, 8, 9, 10, 11],
[12, 13, 14, 15, 16, 17],
[18, 19, 20, 21, 22, 23]])
"""
t[[1, 3]] # t[[1, 3], :]
"""
array([[ 6, 7, 8, 9, 10, 11],
[18, 19, 20, 21, 22, 23]])
"""
取列
t[:,2]
"""
array([ 2, 8, 14, 20])
"""
# 取列[:,2]前面的:不能省略, 表示所有行都要
t[:, 2::]
"""
array([[ 2, 3, 4, 5],
[ 8, 9, 10, 11],
[14, 15, 16, 17],
[20, 21, 22, 23]])
"""
t[:, [1, 2, 3]]
"""
array([[ 1, 2, 3],
[ 7, 8, 9],
[13, 14, 15],
[19, 20, 21]])
"""
同时取行和列
t[2,3]
# 15 表示取3行4列的元素
t[1:3,2:5]
"""
array([[ 8, 9, 10],
[14, 15, 16]])
"""
t[[0, 1, 2], [2, 3, 4]]
"""
array([ 2, 9, 16])
"""
Ⅷ. 修改数组值
t 10
"""
array([[ True, True, True, True, True, True],
[ True, True, True, True, False, False],
[False, False, False, False, False, False],
[False, False, False, False, False, False]])
"""
t[t 10] = 100
"""
array([[100, 100, 100, 100, 100, 100],
[100, 100, 100, 100, 10, 11],
[ 12, 13, 14, 15, 16, 17],
[ 18, 19, 20, 21, 22, 23]])
"""
t = np.arange(24).reshape(4,6)
"""
array([[ 0, 1, 2, 3, 4, 5],
[ 6, 7, 8, 9, 10, 11],
[12, 13, 14, 15, 16, 17],
[18, 19, 20, 21, 22, 23]])
"""
np.where(t 10, 0, 100)
"""
array([[ 0, 0, 0, 0, 0, 0],
[ 0, 0, 0, 0, 100, 100],
[100, 100, 100, 100, 100, 100],
[100, 100, 100, 100, 100, 100]])
"""
t = np.arange(24).reshape(4,6)
t.clip(10, 18)
"""
array([[10, 10, 10, 10, 10, 10],
[10, 10, 10, 10, 10, 11],
[12, 13, 14, 15, 16, 17],
[18, 18, 18, 18, 18, 18]])
小于10的替换成10,大于18的替换为18,不能替换nan
"""
t = t.astype(float)
"""
array([[ 0., 1., 2., 3., 4., 5.],
[ 6., 7., 8., 9., 10., 11.],
[12., 13., 14., 15., 16., 17.],
[18., 19., 20., 21., 22., 23.]])
"""
t[3, 3] = np.nan
"""
array([[ 0., 1., 2., 3., 4., 5.],
[ 6., 7., 8., 9., 10., 11.],
[12., 13., 14., 15., 16., 17.],
[18., 19., 20., nan, 22., 23.]])
"""
t.clip(10, 18)
"""
array([[10., 10., 10., 10., 10., 10.],
[10., 10., 10., 10., 10., 11.],
[12., 13., 14., 15., 16., 17.],
[18., 18., 18., nan, 18., 18.]])
"""
Ⅸ. nan 特性
两个 nan
是不相等的。
np.nan == np.nan
# False
根据这个特性,判断一个数组中有多少个 nan
t
"""
array([[ 0., 1., 2., 3., 4., 5.],
[ 6., 7., 8., 9., 10., 11.],
[12., 13., 14., 15., 16., 17.],
[18., 19., 20., nan, 22., 23.]])
"""
np.count_nonzero(t!=t)
# 1
判断一个数字是不是 nan
np.isnan(t[3, 3])
# True
np.isnan(t)
"""
array([[False, False, False, False, False, False],
[False, False, False, False, False, False],
[False, False, False, False, False, False],
[False, False, False, True, False, False]])
"""
t[np.isnan(t)] = 0
"""
array([[ 0., 1., 2., 3., 4., 5.],
[ 6., 7., 8., 9., 10., 11.],
[12., 13., 14., 15., 16., 17.],
[18., 19., 20., 0., 22., 23.]])
"""
nan
与任何值计算都为 nan
t
"""
array([[ 0., 1., 2., 3., 4., 5.],
[ 6., 7., 8., 9., 10., 11.],
[12., 13., 14., 15., 16., 17.],
[18., 19., 20., nan, 22., 23.]])
"""
t.sum() # np.sum(t)
# nan
np.sum(t, axis=0)
"""
array([36., 40., 44., nan, 52., 56.])
"""
求和 np.sum()
方法里的参数 axis
表示轴的意思,一维数组一个轴,就是 0
二维数组两个轴 0, 1
三维数组三个轴 0, 1, 2
Ⅹ. numpy 中常用的统计函数
- 求和
np.sum(a, axis=None)
- 均值
np.mean(a, axis=None)
- 中值
np.median(a, axis=None)
- 最大值
np.max(a, axis=None)
- 最小值
np.min(a, axis=None)
- 极差
np.ptp(a, axis=None)
- 标准差
np.sed(a, axis=None)
标准差公式
这里都只列举的两个参数,更多参数作用可以参考源代码。
Ⅺ. 数组的拼接
竖直拼接
t1 = np.arange(24).reshape(4, 6)
"""
array([[ 0, 1, 2, 3, 4, 5],
[ 6, 7, 8, 9, 10, 11],
[12, 13, 14, 15, 16, 17],
[18, 19, 20, 21, 22, 23]])
"""
t2 = np.arange(24, 48).reshape(4, 6)
"""
array([[24, 25, 26, 27, 28, 29],
[30, 31, 32, 33, 34, 35],
[36, 37, 38, 39, 40, 41],
[42, 43, 44, 45, 46, 47]])
"""
np.vstack((t1, t2))
"""
array([[ 0, 1, 2, 3, 4, 5],
[ 6, 7, 8, 9, 10, 11],
[12, 13, 14, 15, 16, 17],
[18, 19, 20, 21, 22, 23],
[24, 25, 26, 27, 28, 29],
[30, 31, 32, 33, 34, 35],
[36, 37, 38, 39, 40, 41],
[42, 43, 44, 45, 46, 47]])
"""
水平拼接
np.hstack((t1, t2))
"""
array([[ 0, 1, 2, 3, 4, 5, 24, 25, 26, 27, 28, 29],
[ 6, 7, 8, 9, 10, 11, 30, 31, 32, 33, 34, 35],
[12, 13, 14, 15, 16, 17, 36, 37, 38, 39, 40, 41],
[18, 19, 20, 21, 22, 23, 42, 43, 44, 45, 46, 47]])
"""
XII. 其他方法
- 获取最大最小值位置,
np.argmax(a, axis=None)
np.argmin(a, axis=None)
- 创建一个全为 0 的数组,
np.zeros((行, 列))
- 创建一个全为 1 的数组,
np.ones((行, 列))
- 创建一个对角线为 1 的正方形数组(方阵),
np.eys(3)
生成随机数
np.random.rand(d0, d1, d2, ... , dn)
n 维度均匀分布随机数组,范围0 ~ 1
np.random.randn(d0, d1, d2, ... , dn)
n 维度正态分布随机数组,平均数 0,标准差 1np.random.randint(low, high, (行, 列))
范围[low, high)
np.random.uniform(low, high, (行, 列)
浮点数np.random.normal(loc, scale, (行, 列))
指定正态分布抽取样本,分布中心loc
,标准差scale
np.random.seed()
随机种子,c/c++常用操作srand((unisgned)time(NULL))
Reference
[1]numpy 中文网: https://www.numpy.org.cn/user/basics/types.html#数组类型之间的转换
- END -