Numpy
NumPy是一个开源的Python科学计算基础库,包含:
- 一个强大的N维数组对象
ndarray - 广播功能函数
- 整合
C/C++/Fortran代码的工具 - 线性代数、傅里叶变换、随机数生成等功能
导入使用:
import numpy as np
N维数组对象:ndarray
ndarray: 数组(在程序中的别名是:array)
- 一个多维数组(注:这里的维度是指数据的组织形式):
- 1维数组:1层,eg:
[],可用来表示一个向量 - 2维数组:2层,eg:
[[],[],...,[]],可用来表示一个矩阵 - N维数组:N层数组,可用来表示多个矩阵
- 1维数组:1层,eg:
- 由两部分构成:
- 实际的数据
- 描述这些数据的元数据(数据维度、数据类型等)
- 元素类型:
- 一般要求为相同(同质)类型
- 也可以由非同质对象构成,此时元素类型为object,无法有效发挥NumPy优势,尽量避免使用
- vs. Python
list列表:ndarray对象采用相同的数据类型(有助于节省运算和存储空间)ndarray对象运算更直接高效(如:可去掉元素间运算所需的循环,使一维向量更像单个数据)
ndarray对象的属性
| 属性 | 说明 |
|---|---|
.ndim |
秩(轴数量或维度数量) |
.shape |
每个维度的尺度,返回一个tuple (eg: (n,),(n,m),(a,b,c)) |
.size |
元素个数(=.shape中n*m*...) |
.dtype |
元素类型 |
.itemsize |
每个元素的大小,以字节为单位 |
ndarray的元素类型
对比Python语法仅支持整数、浮点数和复数3种类型,ndarray支持更多的元素类型,因为:
- 科学计算涉及数据较多,对存储和性能都有较高要求
- 对元素类型精细定义,有助于NumPy合理使用存储空间并优化性能
| 数据类型 | 说明 |
|---|---|
bool |
布尔类型,True或False |
intc |
与C语言中的int类型一致,一般是int32或int64 |
intp |
用于索引的整数,与C语言中ssize_t一致,int32或int64 |
int8 |
字节长度的整数,取值:[‐128, 127] |
int16 |
16位长度的整数,取值:[‐32768, 32767] |
int32 |
32位长度的整数,取值:[‐2^31, 2^31‐1] |
int64 |
64位长度的整数,取值:[‐2^63, 2^63‐1] |
uint8 |
8位无符号整数,取值:[0, 255] |
uint16 |
16位无符号整数,取值:[0, 65535] |
uint32 |
32位无符号整数,取值:[0, 2^32‐1] |
uint64 |
64位无符号整数,取值:[0, 2^64‐1] |
float16 |
16位半精度浮点数:1位符号位,5位指数,10位尾数 |
float32 |
32位半精度浮点数:1位符号位,8位指数,23位尾数 |
float64 |
64位半精度浮点数:1位符号位,11位指数,52位尾数 |
complex64 |
复数类型,实部和虚部都是32位浮点数 |
complex128 |
复数类型,实部和虚部都是64位浮点数 |
ndarray数组的创建
| 函数 | 说明 | 示例 |
|---|---|---|
np.array(list/tuple,dtype=None) |
从list/tuple/array等类型创建(不指定dtype时,将根据数据情况自动关联一个dtype类型) |
np.array([i for i in range(10)]) |
np.zeros(shape,dtype=float) |
根据shape生成一个全0数组(shape: int or tuple) |
np.zeros(shape=(3,5),dtype=int) |
np.ones(shape,dtype=float) |
根据shape生成一个全1数组(shape: int or tuple) |
np.ones(shape=(3,5),dtype=int) |
np.full(shape,fill_value,dtype=None) |
根据shape生成一个全是fill_value的数组(shape:int or tuple,dtype默认根据fill_value的数据类型) |
np.full(shape=(3,5),fill_value=6 |
np.zeros_like(a,dtype=None) |
根据数组a的形状生成一个全0数组(dtype默认根据a的dtype) |
np.zeros_like(a) |
np.ones_like(a,dtype=None) |
根据数组a的形状生成一个全1数组(dtype默认根据a的dtype) |
np.ones_like(a) |
np.full_like(a,val,dtype=None) |
根据数组a的形状生成一个全是val的数组(dtype默认根据a的dtype) |
np.full_like(a,0.1,dtype=float) |
np.arange([start=0,] stop[, step=1,], dtype=None) |
[start,stop-1]等step间隔形成一维数组(类似range(),但可以是浮点数) |
np.arange(0,1,0.2) |
np.linspace(start, stop, num=50,endpoint=True,dtype=None) |
[start,stop]等间距提取num个数据形成一维数组(endpoint=True: 默认sample包括stop) |
np.linspace(0,20,11) |
np.eye(n,dtype=float) |
创建一个正方的n*n单位矩阵(对角线为1,其余为0) |
np.eye(3) |
np.random.randint([low=0,] high, size=None, dtype='l') |
[low,high)随机整数数组(size: int or tuple for output shape),默认生成一个数 |
np.random.randint(5, size=(2, 4)) |
np.random.random(size=None) |
[0.0,1.0)随机均匀分布的浮点数数组(size: int or tuple for output shape),默认生成一个数 |
np.random.random((3, 2)) |
np.random.normal(loc=0.0, scale=1.0, size=None) |
生成符合loc均值,scale方差的随机正态分布的浮点数数组(size: int or tuple for output shape),默认生成一个数 |
np.random.normal(loc=0,scale=10,size=(3,5)) |
np.random.shuffle(a) |
根据数组a的0轴进行随排列(行乱序),改变原数组 | np.random.shuffle(X) |
np.random.permutation(a) |
根据数组a的0轴进行随排列(行乱序),生成一个新数组 | X1=np.random.permutation(X) |
np.random.choice(a, size=None, replace=True, p=None) |
从a(一维数组或int)中以概率p抽取元素,形成size形状新数组 replace表示是否可以重用元素 | np.random.choice(a) |
Samples
np.arrayx=np.array([i for i in range(10)]) # array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]) y=np.array((1.1, 2, 3.5)) # array([1.1, 2. , 3.5]) X=np.array([ [1, 2], [3, 4] ]) # array([[1, 2],[3, 4]]).ndim,.shape,.size,.dtype,.itemsize# 1, (10,), 10, dtype('int64'), 8 x.ndim, x.shape, x.size, x.dtype, x.itemsize # 1, (3,), 3, dtype('float64'), 8 y.ndim, y.shape, y.size, y.dtype, y.itemsize # 2, (2, 2), 4, dtype('int64'), 8 X.ndim, X.shape, X.size, X.dtype, X.itemsize # 注意: a 与 b 的维度不同 a,b = np.array([1,2,3]), np.array([[1,2,3]]) # 1, (3,), 3 a.ndim,a.shape,a.size # 2, (1, 3), 3 b.ndim,b.shape,b.sizenp.zeros,np.ones,np.full# np.zeros(shape,dtype=float) np.zeros(5) # array([0., 0., 0., 0., 0.]) np.zeros(5,dtype=int) # array([0, 0, 0, 0, 0]) np.zeros(shape=(3,2),dtype=int) # array([[0, 0], [0, 0], [0, 0]]) # np.ones(shape,dtype=float) np.ones(5) # array([1., 1., 1., 1., 1.]) np.ones(5,dtype=int) # array([1, 1, 1, 1, 1]) np.ones(shape=(3,2),dtype=int) # array([[1, 1], [1, 1], [1, 1]]) # np.full(shape,fill_value,dtype=None) np.full(5,2) # array([2, 2, 2, 2, 2]) np.full((3,2),2.5) # array([[2.5, 2.5], [2.5, 2.5], [2.5, 2.5]])np.zeros_like,np.ones_like,np.full_likeX # array([[1, 2], [3, 4]]) # np.zeros_like(a,dtype=None) np.zeros_like(X) # array([[0, 0], [0, 0]]) # np.ones_like(a,dtype=None) np.ones_like(X) # array([[1, 1], [1, 1]]) # np.full_like(a,val,dtype=None) np.full_like(X,2.5) # array([[2, 2],[2, 2]]) np.full_like(X,2.5,dtype=float) # array([[2.5, 2.5], [2.5, 2.5]])np.arange,np.linspace# np.arange([start=0,] stop[, step=1,], dtype=None) => [start,stop-1] np.arange(5) # array([0, 1, 2, 3, 4]) np.arange(0,5) # array([0, 1, 2, 3, 4]) np.arange(0,10,2) # array([0, 2, 4, 6, 8]) np.arange(0,5.0) # array([0., 1., 2., 3., 4.]) np.arange(0,1,0.2) # array([0. , 0.2, 0.4, 0.6, 0.8]) # np.linspace(start, stop, num=50,endpoint=True,dtype=None) => [start,stop] np.linspace(0,10,5) # array([ 0. , 2.5, 5. , 7.5, 10. ]) np.linspace(0,10,6) # array([ 0., 2., 4., 6., 8., 10.]) np.linspace(0,10,5,endpoint=False) # array([0., 2., 4., 6., 8.])np.eye# np.eye(n,dtype=float) => n*n I np.eye(2) # array([[1., 0.], [0., 1.]])np.random.randint,np.random.random,np.random.normal,np.random.seed# np.random.randint([low=0,] high, size=None, dtype='l') => [low, high) 均匀分布的整数 np.random.randint(0,10) # 7 np.random.randint(0,10,size=5) # array([6, 3, 9, 5, 4]) np.random.randint(0,10,size=(2,6)) # array([[0, 5, 5, 2, 2, 6], [5, 3, 5, 7, 4, 3]]) # np.random.random(size=None) => [0.0, 1.0) 均匀分布的浮点数 np.random.random() # 0.35112599596274263 np.random.random(size=5) # array([0.84018916, 0.6768928 , 0.37947955, 0.10752063, 0.42760159]) np.random.random(size=(2,3)) # array([[0.3148762 , 0.87591898, 0.29565754], [0.97317656, 0.58963764, 0.19674398]]) # np.random.normal(loc=0.0, scale=1.0, size=None) => 正态分布的浮点数 np.random.normal() # -1.6000374192847393 : 均值为0,方差为1的一个随机浮点数 np.random.normal(10,100) # -83.71302590581439 : 均值为10,方差为100的一个随机浮点数 np.random.normal(loc=0,scale=10,size=(2,3)) # array([[-5.43979747, 16.91181992, -4.96602424], [-5.8348921 , -8.60388572, -9.39083007]]) # np.random.seed(seed=None) => 生成随机数前设置一个随机种子,保证生成的随机数一样 np.random.seed(55) np.random.randint(10) # 7 np.random.randint(10) # 8 : 未使用相同的seed,生成的随机数不一样 np.random.seed(55) np.random.randint(10) # 7 : 使用相同的seed,生成的随机数一样 np.random.seed(55) np.random.randint(10) # 7 : 使用相同的seed,生成的随机数一样 np.random.seed(55) np.random.randint(100) # 83 : seed相同,范围不同,生成的随机数不一样np.random.shuffle,np.random.permutation,np.random.choice''' X: array([[ 0, 1, 2, 3, 4], [ 5, 6, 7, 8, 9], [10, 11, 12, 13, 14]]) ''' np.random.shuffle(X) # 根据数组a的0轴进行随排列 => 行乱序,直接改变原数组 X ''' array([[10, 11, 12, 13, 14], [ 5, 6, 7, 8, 9], [ 0, 1, 2, 3, 4]]) ''' Y=np.random.permutation(X) # 根据数组a的0轴进行随排列 => 行乱序,不改变原数组 ''' array([[10, 11, 12, 13, 14], [ 0, 1, 2, 3, 4], [ 5, 6, 7, 8, 9]]) ''' np.random.choice(10,(2,3)) # = np.random.randint(0,10,(2,3)) ''' array([[8, 7, 1], [5, 7, 8]]) ''' np.random.choice(5, 3, replace=False, p=[0.1, 0, 0.3, 0.6, 0]) ''' 从 array[0,1,2,3,4] 中按概率p无重复的随机挑出3个(元素1,4取出的概率为0) => array([2, 3, 0]) '''
ndarray数组的基础操作
变换
维度变换
方法 说明 .reshape(shape)返回一个shape形状的新数组(注:数组元素个数一致) .resize(shape)与 .reshape(shape)功能一致,但修改原数组.swapaxes(ax1,ax2)将数组 n个维度中两个维度进行调换,返回一个新数组,原数组不变.flatten()对数组进行降维,返回折叠后的一维数组,原数组不变 元素类型变换
方法 说明 dtype=np.array(a,dtype=np.int32)创建时指定astype()a.astype(np.float)返回一个新数组
Sample1:维度变换
x=np.arange(10) # array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
# 1. reshape(shape) => 原数组不变
x.reshape(2,5) # array([[0, 1, 2, 3, 4],[5, 6, 7, 8, 9]])
# => Note: 原数组x不变 = array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
x.reshape(2,-1) # array([[0, 1, 2, 3, 4],[5, 6, 7, 8, 9]])
# => Note: x.reshape(3,-1)会出错,因为10不能被3整除
x.reshape(1,-1) # array([[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]])
# => Note: 生成的是一个新的1*10的二维数组(矩阵),不是一维数组(向量)
# 2. resize(shape) => 原数组改变
x.resize(5,2) # None
x # array([[0, 1],[2, 3],[4, 5],[6, 7],[8, 9]])
# 3. swapaxes(ax1,ax2) => 原数组不变
# 2, (5,2)
x.ndim,x.shape
x.swapaxes(0,1) # array([[0, 2, 4, 6, 8],[1, 3, 5, 7, 9]])
# => 0,1 维度数据交换
# 4. flatten() => 原数组不变
x.flatten() # array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
# => 压缩到一维
Sample2:元素类型变换
a # array([1, 2, 3])
a.dtype # dtype('int64')
# 1. dtype=xxx
c = np.array(a,dtype=np.int32) # array([1, 2, 3], dtype=int32)
# 2. astype(dtype)
d = a.astype(float) # array([1., 2., 3.])
访问
- 索引: 获取数组中特定位置元素
- 每个维度一个索引值,逗号分割
- 切片: 获取数组元素子集
- 每个维度一个切片,逗号分割
- 一个切片使用3元素冒号分割(
起始编号: 终止编号(不含): 步长)
- 注意:
- 编号
0开始从左递增,或‐1开始从右递减 - 切片产生的子数组是原数组的引用(创建与原数组无关的新的子数组可以使用
.copy()复制一份)
- 编号
Sample1:索引
一维数组使用索引
''' x = np.arange(10) => array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]) ''' x[2] # 2 x[-1] # 9- 二维数组使用索引
''' X = np.arange(10).reshape(3,5) => array([[ 0, 1, 2, 3, 4], [ 5, 6, 7, 8, 9], [10, 11, 12, 13, 14]]) ''' X[2][2] # 12 X[(2,2)] # 12 X[2,2] # 12 <= 推荐方式
- 二维数组使用索引
Sample2:切片
一维数组使用切片
''' x = np.arange(10) => array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]) ''' x[5:9:2] # [5,9),step:2 => array([5, 7]) x[5:9] # [5,9),step:1 => array([5, 6, 7, 8]) x[:5] # [s,5),s=0 => array([0, 1, 2, 3, 4]) x[5:] # [5,e),e=len => array([5, 6, 7, 8, 9]) x[::2] # step:2 => array([0, 2, 4, 6, 8]) x[::-1] # step:-1 => array([9, 8, 7, 6, 5, 4, 3, 2, 1, 0]) 倒数二维数组使用切片
''' X = np.arange(10).reshape(3,5) => array([[ 0, 1, 2, 3, 4], [ 5, 6, 7, 8, 9], [10, 11, 12, 13, 14]]) ''' X[0], X[0,:] # 取第0行 array([0, 1, 2, 3, 4]) X[:,0] # 取第0列 array([ 0, 5, 10]) X[::-1,::-1] # 行列都反转 ''' array([[14, 13, 12, 11, 10], [ 9, 8, 7, 6, 5], [ 4, 3, 2, 1, 0]]) ''' X[:2,::2] # 取前2行,列step为2的元素 ''' array([[0, 2, 4], [5, 7, 9]]) ''' X[:2,:3] # 取前2*3 (注意与X[:2][:3]的区别) ''' array([[0, 1, 2], [5, 6, 7]]) ''' X[:2][:3] # X[:2]数组的前3个元素 ''' X[:2] array([[0, 1, 2, 3, 4], [5, 6, 7, 8, 9]]) X[:2][:3] array([[0, 1, 2, 3, 4], [5, 6, 7, 8, 9]]) '''切片产生的子数组是原数组的引用
subX=X[:2,:3] # 切片,产生子矩阵数组 ''' array([[0, 1, 2], [5, 6, 7]]) ''' subX[0,0]=100 # 1. 修改子矩阵[0,0]位置的元素值 ''' array([[100, 1, 2], [ 5, 6, 7]]) ''' X # 原数组中[0,0]位置的元素值也改变了 ''' array([[100, 1, 2, 3, 4], [ 5, 6, 7, 8, 9], [ 10, 11, 12, 13, 14]]) ''' X[0,0]=50 # 2. 修改原数组[0,0]位置元素值 ''' array([[50, 1, 2, 3, 4], [ 5, 6, 7, 8, 9], [10, 11, 12, 13, 14]]) ''' subX # 子数组[0,0]位置的元素值也跟着改变了 ''' array([[50, 1, 2], [ 5, 6, 7]]) ''' subX=X[:2,:3].copy() # 3. 使用`.copy()`创建与原数组无关的新的子数组 ''' array([[50, 1, 2], [ 5, 6, 7]]) ''' subX[0,0]=20 # 改变子数组[0,0]位置元素值 ''' array([[20, 1, 2], [ 5, 6, 7]]) ''' X # 原数组不受影响 ''' array([[50, 1, 2, 3, 4], [ 5, 6, 7, 8, 9], [10, 11, 12, 13, 14]]) '''
合并
np.concatenate((a1, a2, ...), axis=0, out=None)- 同维度数组合并
- 不同维度需先
reshape
- more:
np.stack(arrays, axis=0, out=None): Join a sequence of arrays along a new axis.np.vstack(tup): Stack arrays in sequence vertically (row wise).- 垂直方向堆叠,水平方向size需相同(即列size需相同)
- 内部使用
np.concatenate - 特:可直接合并一维数组(向量)
np.hstack(tup): Stack arrays in sequence horizontally (column wise).- 水平方向堆叠,垂直方向size需相同(即行size需相同)
- 内部使用
np.concatenate
np.dstack(tup): Stack arrays in sequence depth wise (along third dimension)
Sample1:np.concatenate
一维数组间(向量)合并
x=np.array([1,2,3]) y=np.array([3,2,1]) z=np.array([6,6,6]) np.concatenate([x,y,z]) # 组成一个新的一维向量: ''' array([1, 2, 3, 3, 2, 1, 6, 6, 6]) '''二维数组间(矩阵)合并
''' A : 2维矩阵(2*3) array([[1, 2, 3], [4, 5, 6]]) ''' np.concatenate([A,A]) # 1. 维度0上合并,组成一个新的4*3矩阵 ''' array([[1, 2, 3], [4, 5, 6], [1, 2, 3], [4, 5, 6]]) ''' np.concatenate([A,A],axis=1) # 维度1上合并,组成2*6矩阵 ''' array([[1, 2, 3, 1, 2, 3], [4, 5, 6, 4, 5, 6]]) ''' np.concatenate([A,A],axis=None) # = flatten 压缩成一维 ''' array([1, 2, 3, 4, 5, 6, 1, 2, 3, 4, 5, 6]) '''一维数组(向量)合并到二维数组(矩阵)中
''' z : 1维向量 array([6,6,6]) A : 2维矩阵(2*3) array([[1, 2, 3], [4, 5, 6]]) ''' np.concatenate([A,z.reshape(1,-1)]) # concatenate只能合并相同维度的数组,z.reshape成2维后再合并 ''' array([[1, 2, 3], [4, 5, 6], [6, 6, 6]]) '''
Sample2:np.vstack,np.hstack
np.vstack''' z : 1维向量 array([6,6,6]) A : 2维矩阵(2*3) array([[1, 2, 3], [4, 5, 6]]) B: 2维矩阵(2*2) array([[1,2], [3,4]]) ''' # 1. 同维数组堆叠 np.vstack([A,A]) # 垂直方向堆叠 A: 2*3矩阵 & A: 2*3矩阵 => 4*3矩阵 ''' array([[1, 2, 3], [4, 5, 6], [1, 2, 3], [4, 5, 6]]) ''' # 2. 不同维数组堆叠 np.vstack([A,z]) # 垂直方向堆叠 A: 2*3矩阵 & z: 1*3向量 => 3*3矩阵 ''' array([[1, 2, 3], [4, 5, 6], [6, 6, 6]]) '''np.hstack''' A : 2维矩阵(2*3) array([[1, 2, 3], [4, 5, 6]]) B: 2维矩阵(2*2) array([[1,2], [3,4]]) ''' np.hstack([A,B]) # 水平方向堆叠 => A: 2*3矩阵 & B: 2*2矩阵 => 2*5矩阵 ''' array([[1, 2, 3, 1, 2], [4, 5, 6, 3, 4]]) '''
分割
np.split(ary, indices_or_sections, axis=0)- more:
np.array_split: Split an array into multiple sub-arrays of equal or near-equal size. Does not raise an exception if an equal division cannot be made.np.hsplit: Split array into multiple sub-arrays horizontally (column-wise).np.vsplit: Split array into multiple sub-arrays vertically (row wise).np.dsplit: Split array into multiple sub-arrays along the 3rd axis (depth).
Sample1:np.split
一维数组(向量)分割
''' x array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]) ''' np.split(x,[3,7]) # 2个分割点:3,7 => 将数组分割成三段 => 生成3个数组 ''' [array([0, 1, 2]), array([3, 4, 5, 6]), array([7, 8, 9])] ''' np.split(x,[5]) # 1个分割点:5 => 将数组分割成两段 => 生成2个数组 ''' [array([0, 1, 2, 3, 4]), array([5, 6, 7, 8, 9])] '''二维数组(矩阵)分割:
''' A array([[ 0, 1, 2, 3], [ 4, 5, 6, 7], [ 8, 9, 10, 11], [12, 13, 14, 15]]) ''' np.split(A,[2]) # 基于维度0,即行,分割 => 2个2*4数组 ''' [ array([[0, 1, 2, 3], [4, 5, 6, 7]]), array([[ 8, 9, 10, 11], [12, 13, 14, 15]]) ] ''' np.split(A,[2],axis=1) # 基于维度1,即列,分割 => 2个4*2数组 ''' [ array([[ 0, 1], [ 4, 5], [ 8, 9], [12, 13]]), array([[ 2, 3], [ 6, 7], [10, 11], [14, 15]]) ] '''
Sample2:np.vsplit,np.hsplit
np.vsplit''' A array([[ 0, 1, 2, 3], [ 4, 5, 6, 7], [ 8, 9, 10, 11], [12, 13, 14, 15]]) ''' np.vsplit(A,[2]) # 垂直方向分割,分为上下两部分 => 2个2*4数组 ''' [ array([[0, 1, 2, 3], [4, 5, 6, 7]]), array([[ 8, 9, 10, 11], [12, 13, 14, 15]]) ]np.hsplit''' x array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]) A array([[ 0, 1, 2, 3], [ 4, 5, 6, 7], [ 8, 9, 10, 11], [12, 13, 14, 15]]) ''' np.hsplit(x,[3,7]) # 水平方向分割,分为三部分部分 => 3个1维数组 ''' [ array([0, 1, 2]), array([3, 4, 5, 6]), array([7, 8, 9]) ] ''' np.hsplit(A,[2]) # 水平方向分割,分为左右两部分 => 2个4*2数组 ''' [ array([[ 0, 1], [ 4, 5], [ 8, 9], [12, 13]]), array([[ 2, 3], [ 6, 7], [10, 11], [14, 15]]) ] '''
Sample3:应用
'''
data : 4*4矩阵
array([[ 0, 1, 2, 3],
[ 4, 5, 6, 7],
[ 8, 9, 10, 11],
[12, 13, 14, 15]])
'''
X,Y=np.hsplit(data,[-1]) # 分割出最后一列
'''
X: 4*3矩阵
array([[ 0, 1, 2],
[ 4, 5, 6],
[ 8, 9, 10],
[12, 13, 14]])
Y: 4*1矩阵
array([[ 3],
[ 7],
[11],
[15]])
'''
y=Y[:,0] # 取列(Y的子集,是Y的引用) => 1*4向量
'''
array([ 3, 7, 11, 15])
'''
运算
作用于数组的每一个元素
基本操作符:
+,-,*,/,//,%,**>,<,>=,<=,==,!=
一元函数: 数组中各元素进行对应运算
函数 说明 np.abs(x)np.fabs(x)计算数组各元素的绝对值 np.sqrt(x)计算数组各元素的平方根 np.square(x)计算数组各元素的平方 np.log(x)np.log10(x)np.log2(x)计算数组各元素的自然对数、10底对数和2底对数 np.ceil(x)np.floor(x)计算数组各元素的ceiling值、floor值 np.rint(x)计算数组各元素的四舍五入值 np.modf(x)将数组各元素的小数和整数部分以两个独立数组形式返回 np.cos(x)np.cosh(x)np.sin(x)np.sinh(x)np.tan(x)np.tanh(x)计算数组各元素的普通型和双曲型三角函数 np.exp(x)计算数组各元素的指数值 np.sign(x)计算数组各元素的符号值, 1(+),0,‐1(‐)二元函数: 两个数组各元素进行对应运算
函数 说明 np.maximum(x,y)np.fmax()np.minimum(x,y)np.fmin()元素级的最大值/最小值计算 np.mod(x,y)元素级的模运算 np.copysign(x,y)将数组y中各元素值的符号赋值给数组x对应元素
基本运算
+,-,*,/,//,%,**>,<,>=,<=,==,!=(得到bool数组)
作用于数组的每一个元素(与python的list不同)
与标量
''' X: 3*5 矩阵 array([[ 1, 2, 3, 4, 5], [ 6, 7, 8, 9, 10], [11, 12, 13, 14, 15]]) ''' X+2 ''' array([[ 3, 4, 5, 6, 7], [ 8, 9, 10, 11, 12], [13, 14, 15, 16, 17]]) ''' X-2 ''' array([[-1, 0, 1, 2, 3], [ 4, 5, 6, 7, 8], [ 9, 10, 11, 12, 13]]) ''' X*2 ''' array([[ 2, 4, 6, 8, 10], [12, 14, 16, 18, 20], [22, 24, 26, 28, 30]]) ''' X/2 ''' array([[0, 1, 1, 2, 2], [3, 3, 4, 4, 5], [5, 6, 6, 7, 7]]) ''' X//2 ''' array([[0, 1, 1, 2, 2], [3, 3, 4, 4, 5], [5, 6, 6, 7, 7]]) ''' X%2 ''' array([[1, 0, 1, 0, 1], [0, 1, 0, 1, 0], [1, 0, 1, 0, 1]]) ''' 1/X ''' array([[1. , 0.5 , 0.33333333, 0.25 , 0.2 ], [0.16666667, 0.14285714, 0.125 , 0.11111111, 0.1 ], [0.09090909, 0.08333333, 0.07692308, 0.07142857, 0.06666667]]) ''' X>5 ''' array([[False, False, False, False, False], [False, True, True, True, True], [ True, True, True, True, True]]) '''数组与数组
''' A: 2*2 矩阵 array([[0, 1], [2, 3]]) B: 2*2 矩阵 array([[10, 10], [10, 10]]) ''' A+B ''' array([[10, 11], [12, 13]]) ''' A-B ''' array([[-10, -9], [ -8, -7]]) ''' A*B ''' array([[ 0, 10], [20, 30]]) ''' A/B ''' array([[0. , 0.1], [0.2, 0.3]]) ''' A>B ''' array([[False, False], [False, False]]) '''矩阵和向量: 向量和矩阵每一行做运算
''' v: 一维向量 array([1, 2]) A: 2*2 矩阵 array([[0, 1], [2, 3]]) ''' v+A ''' array([[1, 3], [3, 5]]) ''' v-A ''' array([[ 1, 1], [-1, -1]]) ''' v*A ''' array([[0, 2], [2, 6]]) ''' A/v ''' array([[0. , 0.5], [2. , 1.5]]) ''' v>A ''' array([[ True, True], [False, False]]) ''' np.vstack([v]*A.shape[0])+A # = `v+A` ''' A.shape : (2,2) [v]*A.shape[0] : [array([1, 2]), array([1, 2])] np.vstack([v]*A.shape[0]) : 垂直方向上堆叠2个v,生成2*2的矩阵 array([[1, 2], [1, 2]]) => array([[1, 3], [3, 5]]) ''' np.tile(v,(2,1))+A # = `v+A` ''' `np.tile(A,repeats)` np.tile(v,(2,1)) : 将v,行方向上重复2次,列方向上重复1次,形成2*2矩阵 array([[1, 2], [1, 2]]) => array([[1, 3], [3, 5]]) '''
常用运算函数
一元函数
''' X: 3*5 矩阵 array([[ 1, 2, 3, 4, 5], [ 6, 7, 8, 9, 10], [11, 12, 13, 14, 15]]) ''' np.sin(X) ''' array([[ 0.84147098, 0.90929743, 0.14112001, -0.7568025 , -0.95892427], [-0.2794155 , 0.6569866 , 0.98935825, 0.41211849, -0.54402111], [-0.99999021, -0.53657292, 0.42016704, 0.99060736, 0.65028784]]) ''' np.power(3,X) # 3^x , 同 3**X ''' array([[ 3, 9, 27, 81, 243], [ 729, 2187, 6561, 19683, 59049], [ 177147, 531441, 1594323, 4782969, 14348907]]) ''' np.exp(X) # e^x ''' array([[2.71828183e+00, 7.38905610e+00, 2.00855369e+01, 5.45981500e+01, 1.48413159e+02], [4.03428793e+02, 1.09663316e+03, 2.98095799e+03, 8.10308393e+03, 2.20264658e+04], [5.98741417e+04, 1.62754791e+05, 4.42413392e+05, 1.20260428e+06, 3.26901737e+06]]) ''' np.log(X) # ln(X) ''' array([[0. , 0.69314718, 1.09861229, 1.38629436, 1.60943791], [1.79175947, 1.94591015, 2.07944154, 2.19722458, 2.30258509], [2.39789527, 2.48490665, 2.56494936, 2.63905733, 2.7080502 ]]) ''' np.log2(X) # log2(X) ''' array([[0. , 1. , 1.5849625 , 2. , 2.32192809], [2.5849625 , 2.80735492, 3. , 3.169925 , 3.32192809], [3.45943162, 3.5849625 , 3.70043972, 3.80735492, 3.9068906 ]]) ''' np.log10(X) # log10(X) ''' array([[0. , 0.30103 , 0.47712125, 0.60205999, 0.69897 ], [0.77815125, 0.84509804, 0.90308999, 0.95424251, 1. ], [1.04139269, 1.07918125, 1.11394335, 1.14612804, 1.17609126]]) ''' np.sign(X) ''' array([[0, 1, 1, 1, 1], [1, 1, 1, 1, 1], [1, 1, 1, 1, 1]]) '''二元函数
''' A: 2*2 矩阵 array([[0, 1], [2, 3]]) B: 2*2 矩阵 array([[10.0, 10.0], [10.0, 10.0]]) v: 一维向量 array([1, 2]) ''' np.minimum(A,B) ''' B是浮点数,所以运算结果为浮点数 array([[0., 1.], [2., 3.]]) ''' np.maximum(A,v) ''' array([[1, 2], [2, 3]]) ''' np.mod(A,B) ''' = A%B array([[0., 1.], [2., 3.]]) ''' np.mode(A,v) ''' = A%v array([[0, 1], [0, 1]]) '''
线性运算
向量
''' v: array([1, 2]) w: array([2, 3]) ''' v.T # 1. 转置:还是1维行向量,无变化 => array([1,2]) v.dot(w) # 2. 点积(v·w): 结果是一个标量(对应元素相乘后相加) 1*2+2*3 => 8矩阵
''' A: 2*2 矩阵 array([[0, 1], [2, 3]]) B: 2*3 矩阵 array([[0, 1, 2], [3, 4, 5]]) ''' A.T # 1. 转置: 行列交换 ''' array([[0, 2], [1, 3]]) ''' invA = np.linalg.inv(A) # 2. 逆 ''' array([[-1.5, 0.5], [ 1. , 0. ]]) ''' pinvB = np.linalg.pinv(B) # 3. 伪逆: 方阵才有逆,非方阵可使用伪逆(近似逆) ''' array([[-0.77777778, 0.27777778], [-0.11111111, 0.11111111], [ 0.55555556, -0.05555556]]) ''' A.dot(B) # 4. 矩阵乘法(A·B):2*2 · 2*3 => 2*3 ''' array([[ 3, 4, 5], [ 9, 14, 19]]) ''' A.dot(invA) # 5. A · invA => 单位矩阵 ''' array([[1., 0.], [0., 1.]]) ''' B.dot(pinvB) # 6. B · pinvB => 近似单位矩阵:主对角线为1,次对角线几乎为0(浮点误差造成) ''' array([[ 1.00000000e+00, -1.11022302e-16], [ 2.66453526e-15, 1.00000000e+00]]) '''向量 & 矩阵
''' v: array([1, 2]) A: 2*2 矩阵 array([[0, 1], [2, 3]]) ''' v.dot(A) ''' v:1*2 · A:2*2 : 1*2 => auto transfer to vector, 1 dim => array([4, 7]) ''' A.dot(v) ''' A:2*2 · v:1*2 (auto treat as 2*1) : 2*1 => auto transfer to vector, 1 dim => array([2, 8])
高级
聚合(统计函数)
| 函数 | 说明 |
|---|---|
sum(a, axis=None) |
元素之和 |
min(a, axis=None) max(a, axis=None) |
最小值、最大值 |
average(a, axis=None,weights=None) |
加权平均值(expection) |
ptp(a, axis=None) |
元素最大值与最小值的差 |
median(a, axis=None) |
中位数(中值) |
mean(a, axis=None) |
均值 |
std(a, axis=None) |
标准差 |
var(a, axis=None) |
方差 |
percentile(a,q, axis=None) |
百分位 |
prod(a, axis=None) |
元素乘积 |
Note: axis=None 是统计函数的标配参数
Sample
'''
X=np.arange(16).reshape(4,-1)
=>
array([[ 0, 1, 2, 3],
[ 4, 5, 6, 7],
[ 8, 9, 10, 11],
[12, 13, 14, 15]])
'''
np.sum(X) # 120
np.sum(X,axis=0) # 维度0上聚合(压缩维度0,即行)=> 每列的和 => array([24, 28, 32, 36])
np.sum(X,axis=1) # 维度1上聚合(压缩维度1,即列)=> 每行的和 => array([ 6, 22, 38, 54])
np.max(X) # 15
np.max(X,aixs=0) # 维度0上聚合 => 每列最大值 => array([12, 13, 14, 15])
np.max(X,axis=1) # 维度1上聚合 => 每行最大值 => array([12, 13, 14, 15])
np.mean(X) # 7.5
np.mean(X,axis=0) # 维度0上聚合 => 每列均值 => array([6., 7., 8., 9.])
np.mean(X,axis=1) # 维度1上聚合 => 每行均值 => array([ 1.5, 5.5, 9.5, 13.5])
np.average(X) # 7.5
np.average(X,axis=0) # 维度0上聚合 => 每列平均值 => array([6., 7., 8., 9.])
np.average(X,axis=0,,weights=[10,5,1,4]) # 维度0上聚合 => 每列加权平均值 => array([3.8, 4.8, 5.8, 6.8])
np.percentile(X,q=25) # 百分位, 25%的元素都是小于等于的值 => 3.75
np.percentile(X,q=50) # = np.median(X) => 7.5
np.percentile(X,q=0) # = np.min(X) => 0.0
np.percentile(X,q=100) # = np.max(X) => 15.0
np.percentile(X,q=[0,25,50,100]) # array([ 0. , 3.75, 7.5 , 15. ])
np.percentile(X,q=50,axis=0) # 维度0上聚合 => array([6., 7., 8., 9.])
np.percentile(X,q=50,axis=1) # 维度0上聚合 => array([ 1.5, 5.5, 9.5, 13.5])
np.prod(X) # 0
np.prod(X,axis=0) # 维度0上聚合 => array([ 0, 585, 1680, 3465])
np.prod(X,axis=1) # 维度1上聚合 => array([ 0, 840, 7920, 32760])
x=np.random.normal(0,1,size=1000000) #[0,1) 正态分布随机浮点一维数组
np.mean(x) # -0.00019733605984642867 <= 均值,非常趋近0
np.std(x) # 1.0001027608240785 <= 标准差,非常趋近1
np.var(x) # 1.000205532207944 <= 方差,非常趋近1
索引函数
| 函数 | 说明 |
|---|---|
argmin(a, axis=None) argmax(a, axis=None) |
计算数组a中元素最小值、最大值所在的索引 |
unravel_index(index, shape) |
将一维索引重塑成多维索引 |
argsort(a, axis=-1, kind='quicksort', order=None) |
元素排好序,对应的索引组成的数组 |
argpartition(a, kth, axis=-1, kind='introselect', order=None) |
元素分区后,对应的索引组成的数组 |
'''
X
array([[ 0, 1, 2, 3],
[ 4, 5, 6, 7],
[ 8, 9, 10, 11],
[12, 13, 14, 15]])
'''
np.argmin(X) # 扁平化后的,最小值的下标 => 0
np.argmax(X) # 扁平化后的,最大值的下标 => 15
np.argmin(X,axis=0) # 维度0上聚合 => 每列最小值所在的下标 => array([0, 0, 0, 0])
np.unravel_index(12,shape=(4,4)) # (3, 0) <= 将12重塑成多维下标
np.random.shuffle(X) # 对X进行乱序处理
X '''
array([[ 0, 1, 2, 3],
[ 8, 9, 10, 11],
[12, 13, 14, 15],
[ 4, 5, 6, 7]])
'''
np.argsort(x,axis=0) '''
array([[0, 0, 0, 0],
[3, 3, 3, 3],
[1, 1, 1, 1],
[2, 2, 2, 2]])
'''
np.sort(x,axis=0) '''
array([[ 0, 1, 2, 3],
[ 4, 5, 6, 7],
[ 8, 9, 10, 11],
[12, 13, 14, 15]])
'''
x=np.arange(10) # array([ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
np.random.shuffle(x) # 对x进行乱序处理
x # array([3, 5, 2, 7, 6, 0, 8, 1, 9, 4])
np.argpartition(x,5) # <5,=5,>5 => array([5, 0, 2, 7, 9, 1, 4, 6, 8, 3])
np.partition(x,3) # <5,=5,>5 => array([0, 3, 2, 1, 4, 5, 6, 8, 9, 7])
np.argpartition(x,[3,7]) # array([5, 7, 2, 0, 9, 1, 4, 3, 8, 6])
np.partition(x,[3,7]) # array([0, 1, 2, 3, 4, 5, 6, 7, 9, 8])
Fancy Indexing
应用:统计判断,方便抽出符合条件的元素 (且返回的数组维度可控)
使用索引数组
''' x = np.arange(16) array([ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]) ''' x_inds=[1,3,7,12] x[x_inds] # array([ 1, 3, 7, 12]) x_inds=np.array([[0,2],[1,3]]) x[x_inds] ''' array([[0, 2], [1, 3]]) ''' ''' X=x.reshape(4,-1) array([[ 0, 1, 2, 3], [ 4, 5, 6, 7], [ 8, 9, 10, 11], [12, 13, 14, 15]]) ''' row_inds = np.array([0,1,2]) col_inds = np.array([1,2,3]) X[row_inds,0] # array([0, 4, 8]) X[0,col_inds] # array([1, 2, 3]) X[row_inds,col_inds] # array([ 1, 6, 11]) <= nodes [0,1],[1,2],[2,3]使用bool值数组(array中的元素进行批量比较,得到bool值数组)
''' x = np.arange(5) array([ 0, 1, 2, 3, 4 ]) ''' x<3 # array([ True, True, True, False, False]) x[x<3] # array([0, 1, 2]) 2*x == 24-4*x # array([False, False, False, False, True]) x[2*x == 24-4*x] # array([4]) x%2==0 # array([ True, False, True, False, True]) x[x%2==0] # array([0, 2, 4]) np.sum(x<3) # 3 np.count_nonzero(x<3) # 3 np.sum((x>2)&(x<4)) # 1 <= 多个条件,使用位运算符 np.sum((x%2==0)|(x>3)) # 3 np.sum(~(x==0)) # 4 np.any(x==0) # True np.any(x<0) # False np.all(x>=0) # True ''' X=x.reshape(4,-1) array([[ 0, 1, 2, 3], [ 4, 5, 6, 7], [ 8, 9, 10, 11], [12, 13, 14, 15]]) ''' X<6 ''' array([[ True, True, True, True], [ True, True, False, False], [False, False, False, False], [False, False, False, False]]) ''' X[X<6] # array([0, 1, 2, 3, 4, 5]) X[:,3]%3==0 # array([ True, False, False, True]) <= 每行最后一个元素能否被3整除 X[X[:,3]%3==0,:] # 选出最后一个元素可被3整除的行 ''' array([[ 0, 1, 2, 3], [12, 13, 14, 15]]) ''' np.sum(X%2==0) # 8 <= 统计偶数个数 np.sum(X%2==0,axis=0) # array([4, 0, 4, 0]) <= 每列有多少偶数(行方向上压缩) np.sum(X%2==0,axis=1) # array([2, 2, 2, 2]) <= 每行有多少偶数(列方向上压缩)) np.all(X>3,axis=0) # array([False, False, False, False]) <= 每列(行方向上判断) np.all(X>3,axis=1) # array([False, True, True, True]) <= 每行(列方向上判断)
文件存取
CSV文件存取
np.savetxt(fname,X,fmt='%.18e',delimiter=' ',newline='\n',header='',footer='',comments='# ',encoding=None,)frame: 文件、字符串或产生器,可以是.gz或.bz2的压缩文件array: 存入文件的数组fmt: 写入文件的格式,例如:%d%.2f%.18edelimiter: 分割字符串,默认是任何空格
np.loadtxt(fname,dtype=<class 'float'>,comments='#',delimiter=None,converters=None,skiprows=0,usecols=None,unpack=False,ndmin=0,encoding='bytes',max_rows=None,)frame: 文件、字符串或产生器,可以是.gz或.bz2的压缩文件dtype: 数据类型,可选delimiter: 分割字符串,默认是任何空格unpack: 如果True,读入属性将分别写入不同变量
局限:只能有效存储一维和二维数组
X=np.arange(100).reshape(5,20)
np.savetxt("a.csv",X,fmt='%d',delimiter=",")
'''
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,48,49,50,51,52,53,54,55,56,57,58,59
60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79
80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99
'''
Y=np.loadtxt("a.csv",delimiter=",")
'''
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., 48., 49., 50., 51., 52.,
53., 54., 55., 56., 57., 58., 59.],
[60., 61., 62., 63., 64., 65., 66., 67., 68., 69., 70., 71., 72.,
73., 74., 75., 76., 77., 78., 79.],
[80., 81., 82., 83., 84., 85., 86., 87., 88., 89., 90., 91., 92.,
93., 94., 95., 96., 97., 98., 99.]])
'''
多维数据的存取
a.tofile(frame, sep='', format='%s')frame: 文件、字符串sep: 数据分割字符串,如果是空串,写入文件为二进制format: 写入数据的格式
np.fromfile(frame, dtype=float, count=‐1, sep='')frame: 文件、字符串dtype: 读取的数据类型count: 读入元素个数,‐1表示读入整个文件sep: 数据分割字符串,如果是空串,写入文件为二进制
- 注:tofile将array按一维存储,所以读取到后需reshape恢复(可以通过元数据文件来存储数组相关的额外信息)
X=np.arange(100).reshape(2,10,5) # 2*10*5
'''
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, 48, 49]],
[[50, 51, 52, 53, 54],
[55, 56, 57, 58, 59],
[60, 61, 62, 63, 64],
[65, 66, 67, 68, 69],
[70, 71, 72, 73, 74],
[75, 76, 77, 78, 79],
[80, 81, 82, 83, 84],
[85, 86, 87, 88, 89],
[90, 91, 92, 93, 94],
[95, 96, 97, 98, 99]]])
'''
X.tofile("b.txt",sep=",",format="%d") # => 扁平化存储(1维)
'''
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,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99
'''
Y=np.fromfile("b.txt",sep=",")
'''
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., 48., 49., 50., 51.,
52., 53., 54., 55., 56., 57., 58., 59., 60., 61., 62., 63., 64.,
65., 66., 67., 68., 69., 70., 71., 72., 73., 74., 75., 76., 77.,
78., 79., 80., 81., 82., 83., 84., 85., 86., 87., 88., 89., 90.,
91., 92., 93., 94., 95., 96., 97., 98., 99.])
'''
Y.reshape(2,10,5) # reshape回原维度
便捷存取
np.save(fname, array, allow_pickle=True, fix_imports=True),np.savez(fname, array)fname: 文件名,以.npy为扩展名,压缩扩展名为.npzarray: 数组变量
np.load(fname,mmap_mode=None,allow_pickle=True,fix_imports=True,encoding='ASCII')fname: 文件名,以.npy为扩展名,压缩扩展名为.npz
X=np.arange(100).reshape(2,10,5) # 2*10*5
np.save("c.npy",X) # 二进制,包含数组元信息
Y=np.load("c.npy") # 可直接恢复成原数组
'''
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, 48, 49]],
[[50, 51, 52, 53, 54],
[55, 56, 57, 58, 59],
[60, 61, 62, 63, 64],
[65, 66, 67, 68, 69],
[70, 71, 72, 73, 74],
[75, 76, 77, 78, 79],
[80, 81, 82, 83, 84],
[85, 86, 87, 88, 89],
[90, 91, 92, 93, 94],
[95, 96, 97, 98, 99]]])
'''