1.什么是Numpy
NumPy(Numerical Python 的简称)是 Python 语言的一个扩展程序库,支持大量的维度数组与矩阵运算,此外也针对数组运算提供大量的数学函数库。NumPy 的前身是 Numeric,这是一个由 Jim Hugunin 等人开发的一个用于数值计算的扩展程序库。由于 Numeric 的一些问题,Jim Hugunin 创建了另一个库叫 SciPy,用于弥补 Numeric 的一些不足。之后,NumPy 开发人员将 Numeric 和 SciPy 整合成一个新的库——NumPy,这使得 NumPy 在功能上更加完善。
NumPy 的主要特点包括:
-
强大的 N 维数组对象:NumPy 使用一个 n 维数组对象 ndarray,可以方便地存储和操作大型多维数组和矩阵,并提供大量的数学函数库用于数组运算。
-
广播功能:广播是 NumPy 对不同形状数组进行数值计算的方式,它对 NumPy 数组的所有运算都适用。
-
整合 C/C++/Fortran 代码的能力:NumPy 的大量算法都经过优化,可以直接使用 C、C++ 或 Fortran 编写的代码,这样就可以避免 Python 自带的循环的低效率问题。
-
用于线性代数的函数库:NumPy 提供了很多用于线性代数的函数库,如矩阵乘法、矩阵求逆、求解线性方程组等。
-
用于统计学的函数库:NumPy 提供了许多用于统计学的函数,如计算均值、中位数、标准差等。
-
用于随机数的函数库:NumPy 提供了随机数生成的功能,可以生成符合各种分布的随机数。
-
用于快速傅里叶变换的函数库:NumPy 提供了快速傅里叶变换的函数库,用于信号处理和图像处理等领域。
NumPy 在科学计算、数据分析、机器学习等领域有着广泛的应用,是 Python 中最重要的科学计算库之一。
2.Numpy快速入门
NumPy中数组的维称作轴(axis),轴的个数叫做行(rank)。比如:[1, 2, 1],轴的个数为1,行(rank)就是1。
[[ 1., 0., 0.], [ 0., 1., 2.]] 上面这个数组有2行(也就是它是2维的),第一位维度的长度为2(也就是2行),第二维度的长度为3(也就是3列)
NumPy的数组类叫作ndarray,下面是ndarray的几个重要属性:
ndarray.ndim
:数组的轴的个数(就是维数)
ndarray.shape
:数组的维度(是一个元组)。比如矩阵有n行m列,那么shape为(n,m)
ndarray.size
:数组元素的个数。也是shape(n,m)元素的乘积
ndarray.dtype
:数组元素类型的描述。例如:numpy.int32, numpy.int16, and numpy.float64 ;
ndarray.itemsize
:数组每个元素的字节大小。对于类型为floa64的元素,itemsize为8(=64/8,1byte=8bit)
ndarray.data
:数组的缓存数据。通常情况下通过索引获取数据,不必要使用这个属性
以下是numpy的一些常用方法:
import numpy as np
a=np.arange(15) # 生成从0开始(包括0),到15(不包括15)的一维整数数组
b=a.reshape(3,5) # 一维数组重塑为二维数组
print(a)
print(b)
print("b.shape=",b.shape) # 打印数组的形状
print("b.ndim=",b.ndim) # 数组的维度数
print("b.dtype.name=",b.dtype.name) # 数组的数据类型名称
print("b.itemsize=",b.itemsize) # 数组中每个元素的大小(以字节为单位)
print("b.size=",b.size) # 数组中的元素总数
print("b.type=",type(b)) # 数组的类型
print(b.dtype) # NumPy数据类型
# 输出:
'''
[ 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14]
[[ 0 1 2 3 4]
[ 5 6 7 8 9]
[10 11 12 13 14]]
b.shape= (3, 5)
b.ndim= 2
b.dtype.name= int32
b.itemsize= 4
b.size= 15
b.type= <class 'numpy.ndarray'>
int32
'''
创建数组:
a=np.array([1,2,3])
print(a,a.dtype) # 打印a的内容和数据类型
b=np.array([1,2,3,4,5.0])
print(b.dtype) # 由于数组b中包含至少一个浮点数(5.0),所以整个数组的数据类型会被提升为浮点数类型。这通常意味着数组b的数据类型会是float64(在64位系统上)
# 输出:
'''
[1 2 3] int32
float64
'''
创建数组的错误示例:
# 一个常见错误就是:提供给array的参数是多个数字,而不是包含数字的列表
a=np.array(1,2,3,4) # 错误
a=np.array([1,2,3,4]) # 正确
# 输出报错:
'''
TypeError: array() takes from 1 to 2 positional arguments but 4 were given
'''
创建多维数组:
# 创建多维数组
b=np.array([(1,2,3,5),(4,5,6,7)])
b
# 输出:
'''
array([[1, 2, 3, 5],
[4, 5, 6, 7]])
'''
创建多维数组并声明数据类型(常见的数据类型有整数、浮点数、复数、布尔型、字符串、时间日期、自定义等):
# 创建数组的时候,可以声明数组的数据类型
c=np.array([[1,2],[3,4]],dtype=complex) # 复数类型
c
# 输出:
'''
array([[1.+0.j, 2.+0.j],
[3.+0.j, 4.+0.j]])
'''
numpy
中的 zeros()
, ones()
, 和 empty()
函数:
1.zeros()
: 这个函数用于创建元素全为0的数组,可以指定数组的形状和数据类型。例如:
import numpy as np
a = np.zeros((2, 3)) # 创建一个 2x3 的数组,所有元素都是 0
a
# 输出:
'''
array([[0., 0., 0.],
[0., 0., 0.]])
'''
2.ones()
: 这个函数用于创建元素全为1的数组,也可以指定数组的形状和数据类型。例如:
b = np.ones((3, 2)) # 创建一个 3x2 的数组,所有元素都是 1
b
# 输出:
'''
array([[1., 1.],
[1., 1.],
[1., 1.]])
'''
3.empty()
: 这个函数用于创建一个具有指定形状的新数组,但会分配新的内存空间但不设置数组中的值。因此,数组中的值可能是任意的,通常是未初始化的内存内容。其数据类型默认为 float64
,但也可以指定。例如:
c = np.empty((2, 2)) # 创建一个 2x2 的数组,但值可能是任意的
c
# 输出:
'''
array([[0., 0.],
[0., 0.]])
'''
empty()
函数返回数组的内容是未初始化的,这意味着它可能包含任何值,取决于分配给该内存空间的先前内容。因此,通常不建议在不需要随机或未定义值的情况下使用 empty()
。使用这些函数时,明确数据类型需求,并在需要时通过 dtype
参数来指定它。例如:
d = np.zeros((2, 2), dtype=int) # 创建一个 2x2 的数组,所有元素都是 0,数据类型为 int
e = np.ones((3,), dtype=np.complex64) # 创建一个长度为 3 的一维数组,所有元素都是 1+0j,数据类型为 complex64
创建多维数组并声明数据类型(常见的数据类型有整数、浮点数、复数、布尔型、字符串、时间日期、自定义等):
from numpy import pi
print(np.linspace(0,2,9)) # 0-2中等差的9个数
x=np.linspace(0,2*pi,100)
f=np.sin(x) # f结果集
# 输出:
'''
[0. 0.25 0.5 0.75 1. 1.25 1.5 1.75 2. ]
'''
如果数组元素太多,NumPy就会自动跳过中间部分的元素并且只打印边界元素:
print(np.arange(10000))
print(np.arange(10000).reshape(100,100))
# 输出:
'''
[ 0 1 2 ... 9997 9998 9999]
[[ 0 1 2 ... 97 98 99]
[ 100 101 102 ... 197 198 199]
[ 200 201 202 ... 297 298 299]
...
[9700 9701 9702 ... 9797 9798 9799]
[9800 9801 9802 ... 9897 9898 9899]
[9900 9901 9902 ... 9997 9998 9999]]
'''
数组的加减乘除等基本运算:
a=np.array([20,30,40,50])
b=np.arange(4)
c=a-b
print(c) # 减
print(b**2) # 乘
d=10*np.sin(a) # 计算sin函数的结果集
print(d)
print(a<35)
b+=a # 加
print(b)
# 输出:
'''
[20 29 38 47]
[0 1 4 9]
[ 9.12945251 -9.88031624 7.4511316 -2.62374854]
[ True True False False]
[20 31 42 53]
'''
在不同数据类型的数组计算过程中,结果的数据类型自动变为精度更高的数据类型:
a=np.ones(3,dtype=np.int32)
b=np.linspace(0,np.pi,3)
print(b.dtype.name)
c=a+b
print(c,c.dtype.name)
d=np.exp(c*1j)
print(d,d.dtype.name)
# 输出:
'''
float64
[1. 2.57079633 4.14159265] float64
[ 0.54030231+0.84147098j -0.84147098+0.54030231j -0.54030231-0.84147098j] complex128
'''
ndarray这个类有很多对数组的一元操作,比如计算整个数组的所有元素的和:
a=np.random.random((2,3))
print(a)
print(a.sum()) # 所有元素求和
print(a.min()) # 所有元素中的最小值
print(a.max()) # 所有元素中的最大值
# 输出:
'''
[[0.87250384 0.81230807 0.10868113]
[0.16989921 0.19395409 0.97618396]]
3.13353028992432
0.10868112737793678
0.9761839642308886
'''
也可以按轴进行计算,比如:
b=np.arange(12).reshape(3,4)
print(b)
print(b.sum(axis=1)) # 计算每一行的和
print(b.sum(axis=0)) # 计算每一列的和
print(b.cumsum(axis=1)) # 计算每一行的累积和(对于第一行,0,0+1=1,1+2=3,3+3=6)
# 输出:
'''
[[ 0 1 2 3]
[ 4 5 6 7]
[ 8 9 10 11]]
[ 6 22 38]
[12 15 18 21]
[[ 0 1 3 6]
[ 4 9 15 22]
[ 8 17 27 38]]
'''
也可以使用一些通用函数进行计算处理:
B=np.arange(3) # 生成[0,1,2]数组
print(B)
print(np.exp(B)) # 计算e的幂
print(np.sqrt(B)) # 计算每个元素的平方根
C=np.array([2.,-1.,4.])
print(np.add(B,C))
# 输出:
'''
[0 1 2]
[1. 2.71828183 7.3890561 ]
[0. 1. 1.41421356]
[2. 0. 6.]
'''
下面的代码实现一个简单的前馈神经网络(Feedforward Neural Network)的训练过程,该网络包含一个隐藏层。训练是通过迭代优化神经网络的权重和偏置来实现的,具体使用了梯度下降算法(Gradient Descent)结合反向传播(Backpropagation)来更新这些参数:
import numpy as np
# Input array
X=np.array([[1,0,1,0],[1,0,1,1],[0,1,0,1]])
# Output
y=np.array([[1],[1],[0]])
# Sigmoid Function
def sigmoid (x):
return 1/(1 + np.exp(-x))
# Derivative of Sigmoid Function
def derivatives_sigmoid(x):
return x * (1 - x)
# Variable initialization
epoch=5000 # Setting training iterations
lr=0.1 # Setting learning rate
inputlayer_neurons = X.shape[1] # number of features in data set
hiddenlayer_neurons = 3 # number of hidden layers neurons
output_neurons = 1 # number of neurons at output layer
# weight and bias initialization
wh=np.random.uniform(size=(inputlayer_neurons,hiddenlayer_neurons))
bh=np.random.uniform(size=(1,hiddenlayer_neurons))
wout=np.random.uniform(size=(hiddenlayer_neurons,output_neurons))
bout=np.random.uniform(size=(1,output_neurons))
for i in range(epoch):
# Forward Propogation
hidden_layer_input1=np.dot(X,wh)
hidden_layer_input=hidden_layer_input1 + bh
hiddenlayer_activations = sigmoid(hidden_layer_input)
output_layer_input1=np.dot(hiddenlayer_activations,wout)
output_layer_input= output_layer_input1+ bout
output = sigmoid(output_layer_input)
# Backpropagation
E = y-output
slope_output_layer = derivatives_sigmoid(output)
slope_hidden_layer = derivatives_sigmoid(hiddenlayer_activations)
d_output = E * slope_output_layer
Error_at_hidden_layer = d_output.dot(wout.T)
d_hiddenlayer = Error_at_hidden_layer * slope_hidden_layer
wout += hiddenlayer_activations.T.dot(d_output) *lr
bout += np.sum(d_output, axis=0,keepdims=True) *lr
wh += X.T.dot(d_hiddenlayer) *lr
bh += np.sum(d_hiddenlayer, axis=0,keepdims=True) *lr
print(output)
print(bh)
print(wh)
# 输出:
'''
[[0.9794804 ]
[0.96522404]
[0.04480502]]
[[-0.26860034 0.37221959 0.7842923 ]]
[[ 2.40872021 -0.48817713 0.81159704]
[-2.09465169 0.99439973 0.72975946]
[ 2.02487412 -1.07848612 0.40900003]
[-1.02392791 0.81254532 0.4994015 ]]
'''
索引、切片、递归操作:
a=np.arange(10)**3
print(a)
print(a[2:5])
a[:6:2]=-1000 # 0-6之间的元素,每两个元素,第二个等于-1000
print(a)
print(a[::-1]) # 翻转元素
# 输出:
'''
[ 0 1 8 27 64 125 216 343 512 729]
[ 8 27 64]
[-1000 1 -1000 27 -1000 125 216 343 512 729]
[ 729 512 343 216 125 -1000 27 -1000 1 -1000]
'''
使用函数创建多维数组:
# 多维数组
def f(x,y):
return 10*x+y
b=np.fromfunction(f,(5,4),dtype=int)
print(b)
print(b[2,3])
print(b[0:5,1])
print(b[:,1])
print(b[1:3,:])#在第2行和第3行的每一列元素
# 输出:
'''
[[ 0 1 2 3]
[10 11 12 13]
[20 21 22 23]
[30 31 32 33]
[40 41 42 43]]
23
[ 1 11 21 31 41]
[ 1 11 21 31 41]
[[10 11 12 13]
[20 21 22 23]]
'''
对数组进行形状操作:
a=np.floor(10*np.random.random((3,4))) # 向下取整
print(a)
print(a.shape)
# 输出:
'''
[[5. 1. 9. 6.]
[5. 4. 7. 1.]
[2. 1. 9. 2.]]
(3, 4)
'''
print(a.ravel()) # 返回一个平铺的数组
print(a.reshape(6,2)) # 重新改变形状
# 输出:
'''
[5. 1. 9. 6. 5. 4. 7. 1. 2. 1. 9. 2.]
[[5. 1.]
[9. 6.]
[5. 4.]
[7. 1.]
[2. 1.]
[9. 2.]]
'''
z=np.arange(16).reshape(4,4)
z
# 输出:
'''
array([[ 0, 1, 2, 3],
[ 4, 5, 6, 7],
[ 8, 9, 10, 11],
[12, 13, 14, 15]])
'''
z.shape
# 输出:
'''
(4, 4)
'''
z.reshape(-1) # 一行
# 输出:
'''
array([ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15])
'''
z.reshape(1,-1) # 一行
# 输出:
'''
array([[ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]])
'''
z.reshape(-1,1) # 一列
# 输出:
'''
array([[ 0],
[ 1],
[ 2],
[ 3],
[ 4],
[ 5],
[ 6],
[ 7],
[ 8],
[ 9],
[10],
[11],
[12],
[13],
[14],
[15]])
'''
z.reshape(2,-1) # 不管有多少列,只要保证为两行
# 输出:
'''
array([[ 0, 1, 2, 3, 4, 5, 6, 7],
[ 8, 9, 10, 11, 12, 13, 14, 15]])
'''
z.reshape(-1,2) # 不管有多少行,只要保证为2列
# 输出:
'''
array([[ 0, 1],
[ 2, 3],
[ 4, 5],
[ 6, 7],
[ 8, 9],
[10, 11],
[12, 13],
[14, 15]])
'''
以上内容总结自网络,如有帮助欢迎转发,我们下次再见!