## numpy安装
# pip install Numpy
import numpy as np
np.__version__
# 从Python的列表创建array
## 一维数组
arr1 = np.array([0,2,4,6,8])
## 二维数组
arr2 = np.array(
[
[0,2,4,6,8],
[1,3,5,7,9]
]
)
# 从其它库函数数据创建array
from PIL import Image ## 也可以借助cv2
image_dog=Image.open('./images/dog.png')
print(type(image_dog))
image_dog_np=np.array(image_dog)
print(type(image_dog_np))
print(image_dog_np.shape) ## 打印数组的维度
print(image_dog_np.dtype) ## 打印ndarray对象的元素类型
打印结果:

# 使用np.arange创建数组
array_arange = np.arange(0,10,2) ## 创建0-10步数为2的数组,用过Matlab的同学应该很熟悉
# 使用np.zeros创建全零数组
array_zeros = np.zeros((2,3)) ## 创建2行3列的全零数组
# 使用np.full创建指定值的数组
array_full = np.full((2,2),"polars") ## 注意numpy的array同样能够容纳str类型的数据
打印结果:

# 使用np.empty创建一个指定形状和数据类型且未初始化的数组:
array_empty = np.empty([3,2], dtype = float)
## 注:此方法得到的array数据都是未初始化的,这意味着里面的值是不确定的值,未明确赋值前尽量不要用
tips:
# 使用np.random.random创建数组
array_random = np.random.random((3,2)) ## 创建3行2列的数组,里面的值是0-1之间的随机数
一个简单的数组创建的例子:从0开始,已知步长1和-1出现的概率相等,通过各种方式实现1000步的随机漫步。
%%time
# (1)通过内置的random模块以纯Python的方式实现
import random
position = 0
walk = [position]
steps = 1000
for i in range(steps):
step = 1 if random.randint(0, 1) else -1
position += step
walk.append(position)
# 画出折线图
import matplotlib.pyplot as plt
plt.plot(walk[:100])
%%time是一个魔术命令,它是IPython的一部分,可以用来打印整个单元格的执行时间。

%%time
# (2)用np.random模块一次性随机产生
nsteps = 1000
draws = np.random.randint(0, 2, size=nsteps)
steps = np.where(draws > 0, 1, -1)
walk = steps.cumsum()
plt.plot(walk[:100])

对比一下不难发现,相同的问题,基于NumPy的数据处理速度要比纯Python快10到100倍(甚至更快),并且使用的内存更少。
# 将数字 1~6 放入一个 2×3 的矩阵中
grid = np.arange(1, 7).reshape((2, 3))

# 矩阵的转置
grid.T

# 一维矩阵运算
a = np.array([10,20,30,40])
b = np.arange(4)
print(a,b)
print("a+b:",a+b)
print("a-b:",a-b)
print("a*b:",a*b) # 对应项相乘,若a和b大小不同,则会触发广播机制
print("a.*b:",a.dot(b)) # 向量点击 , 等价于np.dot(a, b)

# 二维矩阵运算
a = np.random.randint(0, 10, size = (4, 5))
b = np.random.randint(0, 10, size = (5, 3))
print(np.dot(a, b)) # 此时进行的是矩阵乘法
print("the shape of a.dot(b) is " + str(np.dot(a, b).shape))

arr = np.random.randn(5, 4) # 正态分布随机数据
print(arr)
print('平均值:',np.mean(arr)) ## 等价于arr.mean()
print('求和:',np.sum(arr)) ## 等价于arr.sum()
print('最大值:',np.max(arr)) ## 等价于arr.max()
print('最小值:',np.min(arr)) ## 等价于arr.min()

这个案例有一定门槛,理论上需要对感知机(BP神经网络)有所了解,但是啃下来后则非常有助于之后复现有关的公式,有条件还是建议试试看。
"""
1. 获取输入数据和标签
2. 定义网络,前向传播得到输出
3. 定义损失函数,
4. 训练,反向传播更新网络参数
"""
import numpy as np
N, D_in, H, D_out = 64, 1000, 100, 10
# 输入x和标签y
x = np.random.randn(N, D_in)
y = np.random.randn(N, D_out)
# 初始化参数
w1 = np.random.randn(D_in, H)
w2 = np.random.randn(H, D_out)
learning_rate = 1e-6
for t in range(500):
# 前向传播 batch_size=all
h = x.dot(w1)
h_relu = np.maximum(h, 0)
y_pred = h_relu.dot(w2)
# 损失函数
loss = np.square(y_pred - y).sum()
if t % 100 == 99:print(t, loss)
# 反向传播
grad_y_pred = 2.0 * (y_pred - y)
grad_w2 = h_relu.T.dot(grad_y_pred) # l=s(y) y=f(x) J=[y_dim*x_dim]; grad l/x=sum[grad(l/y)*grad(y/x)] =J^T*grad y
grad_h_relu = grad_y_pred.dot(w2.T)
grad_h = grad_h_relu.copy()
grad_h[h < 0] = 0
grad_w1 = x.T.dot(grad_h)
# 更新参数
w1 -= learning_rate * grad_w1
w2 -= learning_rate * grad_w2
# 一维数组
a1 = np.arange(10)
print(a1)
print("_____________________")
print("获取第五个元素:",a1[4]) ## 取单个元素
print("获取第五到六的元素:",a1[4:6]) ## 切片
print("按照两步等距取样:",a1[::2]) ## 按照固定步长
print("取出最后一个元素:",a1[-1]) ## 使用负数作为索引,这里返回最后一个

# 多维数组
a2 = np.random.randint(0,10,size=(4,6))
print(a2)
print("_____________________")
print("获取第一行元素:\n",a2[0]) #获取指定行元素
print("获取第二列元素:",a2[:,1]) #获取指定列元素
print("获取第三行第二列元素:",a2[2,1]) #获取特定位置元素
print("获取第一行第四列、第二行第五列的元素:",a2[[0,1],[3,4]]) #获取多个指定位置元素
print("获取第二列、第四列的元素:\n",a2[:,[1,3]]) #获取多个指定列的全部数据

# 布尔索引
a3 = np.arange(24).reshape((4,6))
print(a3<10)
print(a3[a3<10])

# 花式索引(利用整数数组进行索引)
a4 = np.arange(12)
i = np.array([1,1,3,8,5])
print(a4[i])
j = np.array([[3,4],[9,7]])
print(a4[j]) # 最终返回的格式跟j一致

# 对一个数组中任意两行做交换
A = np.arange(25).reshape(5,5)
A[[0,1]] = A[[1,0]]
print("交换前两行后:\n",A)

from PIL import Image
image=Image.open('./images/dog.png')
print(type(image))
image=np.array(image)
F = image[...,0]*(256*256) + image[...,1]*256 + image[...,2] #可以思考下为啥要这么处理
number_color = len(np.unique(F))
print(number_color)

def iterate(Z):
# Count neighbours
N = (Z[0:-2,0:-2] + Z[0:-2,1:-1] + Z[0:-2,2:] +
Z[1:-1,0:-2] + Z[1:-1,2:] +
Z[2: ,0:-2] + Z[2: ,1:-1] + Z[2: ,2:])
# Apply rules
birth = (N==3) & (Z[1:-1,1:-1]==0)
survive = ((N==2) | (N==3)) & (Z[1:-1,1:-1]==1)
Z[...] = 0
Z[1:-1,1:-1][birth | survive] = 1
return Z
Z = np.random.randint(0,2,(20,20))
itera = 1000
for i in range(itera):
Z = iterate(Z)
print(Z)

numpy数组间的基础运算是一对一,也就是a.shape==b.shape,但是当两者不一样的时候,就会自动触发广播机制,数组的广播原则如下:
# 数组与数组运算
a = np.array([[ 0, 0, 0],
[10,10,10],
[20,20,20],
[30,30,30]])
b = np.array([0,1,2])
print(a+b) # 对b的[0,1,2]行重复3次,再与a相加

# 数组与数字运算
arr = np.arange(15).reshape(3,5)
#数组中的所有元素都乘2
print(arr*2)

sample = np.arange(15).reshape(3,5)
print(sample)
print("_____________________")
print("减去每列的平均值后:")
mu = sample.mean(axis=0)
result = sample - mu
print(result)

# 更进一步:标准化每个列,使每个单元格相对于其各自的列具有z-score:
(sample - sample.mean(axis=0)) / sample.std(axis=0)

# reshape与resize,改变数组形状
a1 = np.random.randint(0,10,size=(3,4))
print(a1)
print("_____________________")
print("修改为两行六列:")
reshape_a1 = a1.reshape((2,6)) # reshape是将数组转换成指定的形状,然后返回转换后的结果,对于原数组的形状是不会发生改变的
print(reshape_a1)
print("修改为四行三列:")
a1.resize((4,3)) # resize是将数组转换成指定的形状,会直接修改数组本身,并且不会返回任何值
print(a1)

# 将多维数组转换为一维数组(扁平化)
a2 = np.arange(15).reshape((5, 3))
print(a2)
print("_____________________")
a2_flatten = a2.flatten() # 等价于a2.ravel()
print("拉伸后:")
print(a2_flatten)

'''
vstack代表在垂直方向叠加,如果想要叠加成功,那么列数必须一致
hstack代表在水平方向叠加,如果想要叠加成功,那么行数必须一致
concatenate可以手动的指定axis参数具体在哪个方向叠加
#(1)如果axis=0,代表在水平方向叠加
#(2)如果axis=1,代表在垂直方向叠加
#(3)如果axis=None,会先进行叠加,再转化为1维数组
'''
vstack1 = np.random.randint(0,10,size=(3,4))
print('vstack1:\n',vstack1)
vstack2 = np.random.randint(0,10,size=(2,4))
print('vstack2:\n',vstack2)
#垂直方向叠加的两种方式
vstack3 = np.vstack([vstack1,vstack2]) # 等价于np.concatenate([vstack1,vstack2],axis=0)
print('vstack1与vstack2垂直方向叠加:\n',vstack3)

h1 = np.random.randint(0,10,size=(3,4))
print('h1:\n',h1)
h2 = np.random.randint(0,10,size=(3,1))
print('h2:\n',h2)
#水平方向叠加的两种方式
h3 = np.hstack([h1,h2]) # 等价于np.concatenate([h2,h1],axis=1)
print('h1与h2水平方向叠加:\n',h3)

import torch
import numpy as np
### numpy to tensor
npy = np.random.rand(2,3)
tor = torch.from_numpy(npy)
print("Type: {}".format(tor.type()))
print("Shape/size: {}".format(tor.shape))
print("Values:\n{}".format(tor))

### tensor to numpy
tor_one = torch.ones(6)
npy_one = tor_one.numpy()
print("Type: {}".format(npy_one.dtype))
print("Shape/size: {}".format(npy_one.shape))
print("Values:\n{}".format(npy_one))

# 将数组保存到文件中
'''
函数:np.savetxt(frame,array,fmt="%.18e",delimiter=None)
参数说明:
· frame:文件、字符串或产生器,可以是.gz或.bz2的压缩文件
· array:存入文件的数组
· fmt:写入文件的格式,例如:%d %.2f %.18e
· delimter:分割字符串,默认是空格
'''
from PIL import Image
image=Image.open('./images/dog.png')
print(type(image))
image_flatten=np.array(image).flatten()
np.savetxt("../data/image.csv",image_flatten,fmt="%d",delimiter=",")
# 读取文件
'''
函数:np.loadtxt(frame,dtype=np.float,delimiter=None,unpack=False)
参数说明:
· frame:文件、字符串或产生器,可以是.gz或.bz2的压缩文件
· dtype:数据类型,可选
· delimiter:分割字符串,默认是任何空格
· skiprows:跳过前面x行
· usecols:读取指定的列,用元组组合
· unpack:如果True,读取出来的数组是转置后的
'''
#读取csv文件
image_np = np.loadtxt("../data/image.csv",dtype='uint8',delimiter=",")
image = image_np.reshape(700, 639, 3)