#%%
# CY3761 | 2022-01-01 12:57
#%%
# 描述项
#%%
import numpy as np
np
#%%
# 高级操作展示(作业)
#%%
# 给定一个4维矩阵,如何得到最后两维的和?(提示,指定axis进行计算)
#%%
a = np.random.randint(0, 10, (2, 3, 4, 5)) # 四维矩阵 (4个中括号) | 2*3*4*5 = 120
a
#%%
b = a.reshape(-1) # 将其转为一维
print(a.size, b.size) # 两者标量元素个数
print(b, '\n', sum(b), a.sum()) # 求和 | 没有轴参数 所有元素进行累加求和
#%%
# 返回三维数组 | 表示第0维的数组进行求和, 1表示1维的数组进行求和.., -1表示最后一维
"""
6+2=8, 9+7=16, 7+4=11, 7+6=13, 2+9=11
6+4=10, 0+9=9, 4+8=12, 5+8=13, 6+5=11
去二维(第一层)
"""
for _ in range(5):
m = a[0,0,0,_]
n = a[1,0,0,_]
print(m, '+', n, '=', m+n, end=' | ')
print()
for _ in range(5):
m = a[0,0,1,_]
n = a[1,0,1,_]
print(m, '+', n, '=', m+n, end=' | ')
print()
display(a.sum(0))
#%%
a.sum(1) # 计算时需要熟练数组位置
"""
6+0+8=14, 9+5+1=15, 7+2+1=10, 7+6+7=20, 2+7+9=18
6+5+2=13, 0+6+9=14, 4+4+8=16, 5+9+6=20, 6+7+3=16
去三维(第二层)
"""
for _ in range(5):
m = a[0,0,0,_]
n = a[0,1,0,_]
o = a[0,2,0,_]
print(' + '.join(map(str, [m,n,o])), '=', m+n+o, end=' | ')
print()
for _ in range(5):
m = a[0,0,1,_]
n = a[0,1,1,_]
o = a[0,2,1,_]
print(' + '.join(map(str, [m,n,o])), '=', m+n+o, end=' | ')
print()
display(a.sum(1))
#%%
# 2*3效果
for i in range(2):
for j in range(3):
c = a[i][j].reshape(-1)
print(c, sum(c))
# 最后两维的和 一样效果 | 从里到外..
display(a.sum((2, 3)))
display(a.sum((-1, -2)))
#%%
# 给定数组[1, 2, 3, 4, 5],如何得到在这个数组的每个元素[!!之间]插入3个0后的新数组?
#%%
size = 3
a = np.arange(1,5+1) # 左开右闭
shape = a.size + (a.size - 1) * size # 因为在之间插入,所以插入数会少一层
b = np.zeros(shape, dtype=np.uint8) # 构造一个都是0的数组
print(a, b, shape)
# 对数组的特定位置进行赋值 第一个先赋值 后面每隔3个元素再赋值一次
b[::4] = a
print(b)
#%%
# 给定一个二维矩阵(5行4列),如何交换其中两行的元素(提示:任意调整,花式索引)?
#%%
a = np.random.randint(0, 100, (5,4))
print(a.shape, a.size)
a
#%%
# 交换其中两行的元素 这里的行都进行交换了(注意在jupyter使用变量,不同代码段的相同变量容易造成冲突覆盖)
a[[3,4,2,0,1]]
#%%
# 创建一个100000长度的随机数组,使用两种方法对其求三次方(1、for循环;2、NumPy自带方法),并比较所用时间
#%%
# 计算运行时间 (魔法指令) | 后面不能加入其他东西
#%%
%%time
a01 = np.random.randint(0, 10, 100000)
b01 = a01 ** 3
a01[:10], b01[:10] # 各输出10各元素
#%%
%%time
a01 = np.random.randint(0, 10, 100000)
b01 = np.power(a01, 3)
a01[:10], b01[:10] # 各输出10各元素
#%%
%%time
a01 = np.random.randint(0, 10, 100000)
b01 = [_ ** 3 for _ in a01]
a01[:10], b01[:10] # 各输出10各元素
#%%
# 创建一个5行3列随机矩阵和一个3行2列随机矩阵,求矩阵积
#%%
a02 = np.random.randint(0, 10, (5,3))
b02 = np.random.randint(0, 10, (3,2))
a02
#%%
b02
#%%
a02 @ b02
#%%
b02 @ a02 # 不能交换使用
#%%
# 矩阵的每一行的元素都减去该行的平均值(注意,平均值计算时指定axis,以及减法操作时形状改变)
#%%
a03 = np.random.randint(0, 10, (3,5))
a03
#%%
b03 = a03.sum(1) # 每行的求和
b03
#%%
c03 = a03.mean(1) # 每行的平均值 不指定会求所有数的平均值 需要理解轴的概念 | 0 是求每列的平均值
c03
#%%
print(a03.shape, c03.shape)
d03 = c03.reshape(-1,1) # 自动算行数,1列
d03
#%%
print(a03.shape, d03.shape) # 虽然数据上与c类似, 但使用c直接运算会报错
a03 - d03
#%%
# 打印出以下函数(要求使用np.zeros创建8*8的矩阵):
"""
[[0 1 0 1 0 1 0 1]
[1 0 1 0 1 0 1 0]
[0 1 0 1 0 1 0 1]
[1 0 1 0 1 0 1 0]
[0 1 0 1 0 1 0 1]
[1 0 1 0 1 0 1 0]
[0 1 0 1 0 1 0 1]
[1 0 1 0 1 0 1 0]]
"""
#%%
a04 = np.zeros((8,8), dtype=np.uint8) # 8*8的矩阵
a04
#%%
# 奇数行与偶数行
a04[::2,1::2] = 1 # 奇数行(索引为偶数) 从0开始,隔一行 | 偶数列(索引为奇数) 从1开始,隔一格
a04[1::2,::2] = 1 # 偶数行(索引为奇数) 从1开始,隔一行 | 奇数列(索引为偶数) 从0开始,隔一格
a04
#%%
# 正则化一个5行5列的随机矩阵(数据统一变成0~1之间的数字,相当于进行缩小)
# 正则的概念:矩阵A中的每一列减去这一列最小值,除以每一列的最大值减去每一列的最小值(提示:轴axis给合适的参数!!!)
# $\rm{ A = \frac{A - A.min}{A.max - A.min}}$
# A = (A-A.min) / (A.max-A.min)
#%%
a05 = np.random.randint(1, 10, (5,5))
a05
#%%
# 求每列最小值 0
b05 = a05.min(0)
b05
#%%
# 求每列最大值
c05 = a05.max(0)
c05
#%%
(a05-b05) / (c05-b05) # 正则化
#%%
# 如何根据两个或多个条件过滤numpy数组。加载鸢尾花数据,根据[第一列]小于5.0并且[第三列]大于1.5作为条件,进行数据筛选。(提示,需要使用逻辑与运算:&)
#%%
# iris.csv 鸢尾花数据
# 花萼长度, 花萼宽度, 花瓣长度, 花瓣宽度
a06 = np.loadtxt('iris.csv', delimiter=',') # 使用,进行分割
# 设置2个条件
cond0601 = a06[:,0] < 5.0
cond0602 = a06[:,2] > 1.5
cond0603 = cond0601 & cond0602 # 并且 与运算
a06
#%%
a06[cond0603]
#%%
# 计算鸢尾花数据**每一行**的softmax得分(exp表示自然底数e的幂运算)
#%%
print(np.exp(2), np.e, np.e ** 2) # e常量的幂运算 e = 2.718
#%%
a07 = np.array([2,1,0.1])
a07
#%%
b07 = np.exp(a07)
b07
#%%
c07 = b07 / b07.sum()
c07.round(1) # 保留1位小数
#%%
a06[:5]
#%%
d07 = np.exp(a06)
d07[:5]
#%%
e07 = d07 / d07.sum(1).reshape(-1,1) # 计算每一行 需要指定轴
e07 = e07.round(3) # 保留1位小数 | 结果的每一行都是1
e07[:5]
#%%
e07.sum(1).round(0) # 结果的每一行都是1
#%%
不太懂。。