文章目录
生成数组
# N维数组对象——ndarray
data = np.random.randn(n, m) # 随机生成(n,m)维数组
arr = np.array() # array函数可以接受任意序列型对象
np.zeros(n) # 生成长达n*1维数字为0的数组
np.zeros((n, m)) # 生成长达n*m维数字为0的数组
np.empty((2, 3, 2)) # 生成2*3*2的数字为0的数组
np.ones(n) # 这是数字为1的
np.full((n,m),x) # 创建一个由常数填充的数组,第一个参数是数组的形状,第二个参数是数组中填充的常数。
np.eye(n) # 创建单位矩阵,函数中的参数n,则创建n * n的单位矩阵
np.arange(15) # 生成从0到14的数组
np.arange(0, 10, 1) # 开始,结束,间隔
np.asarray() # asarray()将输入的转为ndarray
np.full_like(data,1) # 生成一个和data形状一样但是数值是指定的数组
# 类似的ones_like(data),zeros_like(data),empty_like(data)
数组基本信息
data.shape # 返回(2,3),即数组各个维度的大小
data.ndim # 返回2,即数组有几个维度
data.dtype # 数组的数据类型
数组修改
data.astype(np.float64) # 改变数组的数据类型
data.reshape((2,3)) # 把data数组分成2行3列的形状
np.meshgrid(data,data) # 拼接
切片:数组的切片是原数组的视图,也就是说并不是复制,在视图上的修改意味着在原数组的修改。如果想要复制就arr[3:5].copy()
,[3:5]是左闭右开的哦!
# 多种切片操作
arr[6:8] # 最基本的一位
# 假设arr2是一个3*3数组
arr2[:2] == arr2[:2, :] # 前两行,全部列
arr2[:2, 1:]# 前两行,后两列
arr2[2, 1:] # 选第3行,后两列
数组操作
可以成批操作无需for循环,这种特性称为向量化,等尺寸数组之间都可以逐元素进行操作。
1. 矩阵操作
- 基本运算
data*10, 1/data # 标量计算会把计算参数传给每一个元素进行操作
data*data
data+data
data-data
data>=data # 同尺寸数组可以比较返回一个bool类型数组
np.dot(data.T, data)# 点乘, ==data@data
- 线性代数
np.dot(data.T, data)# 点乘, ==data@data
# 下面是矩阵分解的操作
from numpy.linalg import inv, det, eig, solve
inv(arr) # 求逆矩阵,如果numpy.linalg.LinAlgError: Singular matrix说明不可逆
det(arr) # 求举证的行列数
eig(arr) # 求方阵的特征值和特征向量
solve(A,B) # 求解x的线性系统Ax = B
np.diag(arr) # arr是方阵则返回对角线元素的一维数组,arr是一维数组则会返回由一维数组形成对角线的对角矩阵。
np.trace(arr) # 求arr的对角元素之和
- 转置
data.T # 转置
transpose()
swapaxes()
对于高维数组,可以使用transpose()
用于换轴
arr = np.arange(16).reshape((2, 2, 4))
print(arr.transpose((1, 0, 2))) # 0表示x轴,1 表示y轴,2表示z轴,这里x与y转置
三维数组可以想象为小区,我们创建的arr数组是一个两栋房子,每栋两层,每层四户人家的小区。x与y进行转置,那么对角线上的不动,1栋的2层与2栋的1层交换。
换一种方式理解:
- z轴不变,那么我们把z轴的[…]数据变成一个数,例如:[0,1,2,3]->0。
- 改变之后的数组就从三维变成二维。[[0,1],[2,3]],那就是简单的x,y轴转置了。0,3不变,1,2交换。
对于高维操作还有swapaxes(1,2)
接受一对轴编号作为参数,这里就是y和z轴进行转置操作了。
2. 基本索引
这种数组子集的选择也是返回数组的视图,如果不想改变原数组记得old= x[0].copy()
# 二维数组索引操作arr[0][1] == arr[0,1],不细说了
# 三维
import numpy as np
x = np.arange(12)
x = x.reshape((2, 2, 3))
# 理解:最外面[]分为两个, 次[]两个, 最里面的数据[]三个
print(x)
print(x[0])
# 理解,相当于把最外层[]去掉,留下第一套嵌套[[]]
old = x[0]
old[0] = 24
print(x)
print(old)
3. 布尔索引
之前提到过data>=data
会返回一个bool类型的数组,其实这串数组还可以成为索引。布尔索引经常用在数组中找某个特定数值,再计数。
- 基本用法
import numpy as np
x = np.arange(12)
y = np.full_like(x, 6)
print(x, y)
print(x[x > y]) # == print(x[x > 6])
print(x[x == y], x[x == y].size)
# !=, ~, |, & 都是可以的
注意:布尔数组必须与数组轴索引的长度一致,虽然python不会报错,但是你绝对不想它出现意想不到的错误吧。
- 数据切片
import numpy as np
x = np.random.randn(2, 4)
y = np.array([1, 2])
print(x[y > 1])
print(x[y > 1, 2]) # 对得到的数据进行切片, 前面是行后面是列
- bool索引选择的数组子集是生成了数据的拷贝。
import numpy as np
x = np.random.randn(2, 4)
y = np.array([1, 2])
old = x[y > 1]
old[0][1] = 0
print(x)
print(old)
4. 神奇索引
使用整数数组进行数据索引。
有什么用呢?当我想要索引数组的数据:
- 不是等间隔索引,而是随机选取其中的数据;
- 索引得到的数据的顺序和原数组的顺序不一定一样,想按照自己希望的排序时。
import numpy as np
x = np.empty((8, 4))
for i in range(8):
x[i] = i
# print(x)
print(x[[4, 3, 0, 6]])
# print(x[[4, 3, 0, 6],[0, 3, 1, 2]]) # 返回元素位于(4,0),(3,3),(0,1),(6,2)的数据
# print(x[[4, 3, 0, 6]][:,[0, 3, 1, 2]])# 先生气索引得到行,在切片:行全选,列又进行索引
y = np.random.randn(8)
print(y)
print(y[[-4, 2, 1]]) # 不管是数组是一维还是两维都需要[[]]包裹索引
注意:神奇索引得到数据的拷贝
5. 逐元素操作
参考逐元素操作表:https://blog.csdn.net/weixin_42029733/article/details/89064962
6. 条件逻辑
numpy.where()
是三元表达式 x if condition else y
的向量化版本。
result = np.where(cond, x, y) # 二三参数不一定需要数组,也可以是标量
7. 数值统计
arr.mean(axis=1) # 列与列之间相加求平均
arr.sum(axis=0) # 行与行之间求和
arr.cumsum() # 累加,前1个相加,前两个相加...,多维也可以用axis
arr.cumprod() # 累乘,前1个相乘,前两个相乘...,多维也可以用axis
# srd()标准差,var()方差,min()最小值,max()最大值,argmin()最小值位置,argmax()最大值位置
# 针对布尔值的数组
arr.sum() # 求正数个数
arr.any() # 检查数组是否有True,返回bool
arr.all() # 检查数组是否都是True,返回bool
arr.sort(1) # 排序,列与列之间排序。1 == axis=1。默认从小到大,而且返回的是数组的拷贝
8. 针对一维数组的集合操作
np.unique(arr) # 返回数组中唯一值排序后形成的数组,== sorted(set(arr))
np.intersect1d(x,y) # 计算x,y的交集并且排序
np.union1d(x,y) # 计算x,y的并集并且排序
np.in1d(x,y) # 计算y中的元素是否包含在x中返回一个与x等长的数组
np.setdiff1d(x,y) # 差集,在x但是不在y中的x元素
np.setxor1d(x,y) # 异或集,在x或者y中,但不是x,y交集元素
使用数组进行文本输入输出
numpy可以在硬盘中将数据以文本或者二进制文件的形式存储,这里只讨论二进制文件,因为大部分用户倾向于用pandas来装载文本或表格型数据。未压缩后缀名.npy,压缩后缀名.npz
np.save('output', arr)
np.load('input.npy')
# 存储多个数组在一个文件中
np.savez('output.npy', a=arr, b=arr2)
# 还是用load加载,成功会是一个字典对象,选中其中一个数组可以使用
arr['b']
# 以上都是未压缩的文件输入输出
np.savez_compressed('output.npz', a=arr, b=arr2)