-
案例 求1到10000各个数的倒数
传统做法
def get():
li = []
for i in range(1, 10001):
li.append(1 / i)
return li
应用numpy
def get_2():
li = np.arange(1, 10000)
return 1 / li
什么时候用numpy
在数据处理的过程中,遇到使用”python for循环”实现一些向量化, 矩阵化的操作时,优先考虑使用numpy
numpy数组中必须是统一的数据类型
numpy数组的创建
import numpy as np
# 创建np列表
x = np.array([1,2,3,4,5])
# 设置数组的数据类型
y = np.array([1,2,3,4,5], dtype="float32")
# 二维数组
z = np.array([[1, 2, 3],
[4, 5, 6],
[7, 8, 9]])
从头创建numpy数组
import random
import numpy as np
# 创建长度位5的数组,值都为0
x = np.zeros(5, dtype=int)
# 创建2 * 4的浮点型数组,值都为1
y = np.ones((2, 4), dtype="float32")
# 创建3 * 5的浮点型数组,值都为8.8
z = np.full((3, 5), 8.8)
# 创建3 * 3的单位矩阵
e = np.eye(3)
# 创建线性序列数组,从1开始到15结束,步长为2
f = np.arange(1, 15, 2)
# 创建4个元素的等差数列, 均匀分配0到1
g = np.linspace(0, 1, 4)
# 创建10个元素的数组,形成1~10^9的等比数列
h = np.logspace(0, 9, 10, base=10) # 0 9 代表10的0次方和9次方
# 创建3 * 3的, 在0~1之间分布的随机数数组
i = np.random.random((3, 3))
# 创建均值为0, 标准差为1的正态分布随机数构成的数组
j = np.random.normal(0, 1, (3, 3))
# 创建3 * 3, 0~10的随机整数数组
k = np.random.randint(0, 10, (3, 3))
# 随机重新排列
a = np.array([1,3,2,4])
b = np.random.permutation(a) # 生成新列表
np.random.shuffle(a) # 改变原先的数组
# 随机采样
x1 = np.arange(10, 25, dtype = float)
r = np.random.choice(x1, size=(4, 3)) # 按形状随机采样
p = np.random.choice(x, size=(4, 3), p = x / np.sum(x)) # 按照概率采样
Numpy数组的属性
a = np.random.randint(1, 10, (3, 4))
print(a.shape) # 大小
print(a.ndim) # 维度
print(a.dtype) # 数据类型
(3, 4)
2
int32
数组索引
一维
x = np.arange(10)
print(x[0])
print(x[-1])
0
9
注意:nmupy数组数据类型是强制的,若修改数组元素的类型与数组类型不符,会进行强制类型转换
切片
x = np.arange(10)
print(x[:3])
print(x[1:3])
print(x[3:])
print(x[3:9:2])
print(x[::-1])
# x[start:end:step]
[0 1 2]
[1 2]
[3 4 5 6 7 8 9]
[3 5 7]
[9 8 7 6 5 4 3 2 1 0]
ps:若多维,则以逗号分隔的多个表达式
x = np.random.randint(1, 20, (3, 4))
print(x[1:3, 1:4:2])
print(x[::-1, ::-1])
获取数组的行和列
x = np.random.randint(1, 20, (3, 4))
print(x[1, :]) # 获取第一行 or x[1]
print(x[:, 2]) # 获取第二列
切片是视图,而非副本,若对切片修改,原来的数组也会改变
数组变形
x = np.random.randint(0, 10, (12,))
print(x)
x1 = x.reshape(3, 4) # 转换为三行四列
print(x1)
x2 = x.reshape(1, x.shape[0]) # 转变为1行12列
print(x2)
ps:reshape获得的也是视图,不是副本,修改会改变原数组
一维向量转化为行向量
x = np.random.randint(0, 10, (12,))
print(x)
x1 = x.reshape(3, 4) # 转换为三行四列
print(x1)
x2 = x.reshape(1, x.shape[0]) # 转变为1行12列
print(x2)
一维向量转化为列向量
x = np.arange(10)
x1 = x.reshape(x.shape[0], 1)
x2 = x[:, np.newaxis]
多维向量转化为一维向量
x = np.random.randint(1, 10, (3, 4))
x1 = x.flatten() # 返回的是副本
x2 = x.ravel() # 返回视图
x3 = x.reshape(-1) # 返回视图
数组的拼接
水平拼接:行数相同
x1 = np.array([[1, 2, 3],
[4, 5, 6]])
x2 = np.array([[7, 8, 9],
[10, 11, 12]])
x3 = np.hstack([x1, x2]) # 返回副本
x4 = np.c_[x1, x2] # 返回副本
[[ 1 2 3 7 8 9]
[ 4 5 6 10 11 12]]
垂直拼接 — 非视图
x1 = np.array([[1, 2, 3],
[4, 5, 6]])
x2 = np.array([[7, 8, 9],
[10, 11, 12]])
x3 = np.vstack([x1, x2])
x4 = np.r_[x1, x2]
数组的分裂
x = np.arange(10)
x1, x2, x3 = np.split(x, [2, 7]) # 两个分裂点, 分裂成三个数组
#[x, y] 表示从下标为x或y的数后面分裂
二维数组
x = np.arange(1, 26).reshape(5, 5)
upper, middle, lower = np.hsplit(x, [2, 4]) # 从第二列和第四列后分裂
upper1, middle1, lower1 = np.vsplit(x, [2, 4]) # 从第二行和第四行下分裂
numpy四大运算
向量化运算
与数字加减乘除 – 对所有元素做运算
x = np.arange(1, 6)
print(x + 4)
print(x - 4)
print(x * 4)
print(x / 4)
[5 6 7 8 9]
[-3 -2 -1 0 1]
[ 4 8 12 16 20]
[0.25 0.5 0.75 1. 1.25]
绝对值,三角函数,指数,对数
# 求绝对值
x = np.array([1, -1, -2, -3])
x1 = np.abs(x)
# 计算三角函数
y = np.linspace(0, np.pi, 3) # 取得0, pi/2, pi
y1 = np.sin(y)
y2 = np.cos(y)
y3 = np.tan(y)
# 指数运算
z = np.arange(3)
z1 = np.exp(z)
# 对数运算
r = np.array([1,2,4,8,10])
r1 = np.log2(r)
r2 = np.log10(r)
两个数组运算 ----- 对应位置运算
x1 = np.arange(1, 6)
x2 = np.arange(6, 11)
x1 + x2
x1 - x2
x1 * x2
x1 / x2
矩阵运算
转置
x = np.arange(1, 10).reshape(3, 3)
y = x.T # 矩阵转置
矩阵乘法
x = np.array([[1, 0],
[1, 1]])
y = np.array([[0, 1],
[1, 1]])
print(x.dot(y))
print(y.dot(x))
广播运算
当两个数组在形状上不匹配,那么数组的形式会沿着维度为1 的维度进行扩展以匹配另一个数组的形状
x = np.ones((3, 3))
y = np.arange(3)
print(x + y)
[[1. 2. 3.]
[1. 2. 3.]
[1. 2. 3.]]
y 由[1, 2, 3] 广播为 [[1, 2, 3], [1, 2, 3], [1, 2, 3]
比较运算
x1 = np.random.randint(100, size=(3, 3))
print(x1 > 50) # 得到一个布尔数组
print(np.sum(x1 > 50) # 计算大于50的个数
print(np.all(x1 > 0) # 判断是否所有数都大于0
print(np.any(x1 == 6) # 判断是否有6
print(np.all(x < 90, axis=1) # 按行判断小于90,列则axis=0
print(np.sum((x < 9) & (x > 5)) # 计算小于9且大于5的个数
[[False True False]
[False True False]
[False False False]]
8 # true是1, false是0, 求大于50的个数
true
false
将布尔数组作为掩码
x1 = np.random.randint(100, size=(3, 3))
print(x1[x1 > 50]) # 将所有大于50的数取出
# [x > 50]为布尔数组, 将布尔数组作为掩码,可以取出对应位置为true的数
花哨的索引
x = np.random.randint(100, size = 10)
index = [2, 6, 9]
print(x[index]) # 取出第2, 6, 9位置的数
index2 = [[1, 0],
[2, 3]]
print(x[index2])
# 结果的形状与索引数组一致
[27 93 88]
[[14 50]
[27 56]]
多维数组
x = np.arange(12).reshape(3, 4)
row = np.array([0, 1, 2]) # 行向量
col = np.array([1, 3, 0]) # 列向量
print(x[row, col])
# 广播机制
row2 = row[:, np.newaxis] # 转化为列向量
print(x[row2, col]) # 取第1, 3, 0 行的1, 3, 0列元素
numpy通用函数
数值排序
x = np.random.randint(20, 50, size= 10)
x2 = np.sort(x) # 不改变原始数组
x.sort() # 改变原始数组
# 获取排序后的位置索引(在原数组中对应的位置)
id = np.argsort(x)
最大最小值
# 获取最大最小值
mx = np.max(x)
mi = np.min(x)
# 获取最大最小值的索引
id1 = np.argmax(x)
id2 = np.argmin(x)
数值求和
x = np.arange(1, 6)
print(x.sum())
print(np.sum(x))
y = np.arange(6).reshape(2, 3)
print(np.sum(y, axis=1)) # 按行求和
print(np.sum(y, axis=0)) # 按列求和
print(x.prod()) # 求积
print(np.prod(y, axis=1)) # 按行求积
中位数、均值、方差、标准差
x = np.random.normal(0, 1, size= 10000) # 正太分布图
print(np.median(x)) # 中位数
print(np.mean(x)) # 均值
print(np.var(x)) # 方差
print(np.std(x)) # 标准差
c++党,但看懂了,默默的点个赞
我也是c++hh,最近学个python