这篇文章是笔者为了复习计算物理的期末考试而写的,由于笔者是物理系学生,初次接触Python,所以可能会有很多错误,欢迎指正。
目录
1. 零碎的基础知识
format函数
print('{0}说圆周率大约为{1:.2f}'.format('老师', 3.14159265))
<< 老师说圆周率大约为3.14
list列表
list列表通过[ ]或list( )定义。
(1)列表生成式:
print([num for num in range(10)])
<< [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
(2)常用列表操作(对列表本身进行操作,并不是得到一个新列表)
· list.reverse( ) → list中元素颠倒,返回NONE
· list.pop( ) → 删去list中最后的元素,返回最后一个元素
· list.append('a') → 在list中最后添加1个元素'a',返回NONE(传函是列表时,也作为一整个元素添加)(通过创建空列并循环append,可实现逐步存入)
· list.insert(2, 'a') → 在list中第2个索引处插入‘a’,返回NONE
list.reverse( ) #list中元素颠倒,返回NONE
list.pop( ) #删去list中最后的元素,返回最后一个元素
list.append('a') #在list中最后添加1个元素'a',返回NONE(传函是列表时,也作为一整个元素添加)(通过创建空列并循环append,可实现逐步存入)
list.insert(2, 'a') #在list中第2个索引处插入‘a’,返回NONE
(3)列表切片
A=[0,1,2,3,4]
B=A[1:4]
C=A[::-1]
D=A[::2]
print(B,C,D)
<< [1, 2, 3] [4, 3, 2, 1, 0] [0, 2, 4]
切片操作是不会改变原列表的,比如C=A[::-1]就与A.reverse()不同,是生成一个新列表,不会改变A自身。
值得注意的是,在缺省的情况下,Python中的区间选取都是左闭右开的。
set集合
空集合只能用set( )定义,非空集合通过{a,b,...}或set([…])函数定义。
逻辑运算:
并集 |
交集 &
差集 -(A-B:属于A但不属于B元素)
对称差集 ^ (A^B:既不在A也不在B的元素)
注意:只有集合能进行逻辑运算,对于列表,可以先转换为集合,运算后再转换回列表。如list(set(A)&set(B))
dict字典
空字典通过{ }或dict( )函数定义,非空字典通过{'key1':'value1', 'key2':'value2', …}或dict([ ])定义。
字典的每个key和value一一对应。如下所示,'1'和'2'就是key,'a''b'
d = {'1':'a','2':'b'}
d['1']
<< 'a'
可通过如下方式添加条目:
d['3']='c'
d
<< d = {'1':'a','2':'b','3':'c'}
tuple元组
通过A=(…)或A="a","b",…定义
元组可视作函数定义中的数组
(1)不定长传入函数
def function(*arg)
其中*代表不定长,其后的arg是元组类型。
(2)zip函数
zip函数用于将可迭代的对象作为参数,将对象中对应的元素打包成一个个元组,然后返回由这些元组组成的列表。
a = [1,2,3]
b = [4,5,6]
c = [4,5,6,7,8]
zipped = zip(a,b) # 返回一个对象
zipped
<< zip object at 0x103abc288>
list(zipped) # list() 转换为列表
<< [(1, 4), (2, 5), (3, 6)]
list(zip(a,c)) # 元素个数与最短的列表一致
<< [(1, 4), (2, 5), (3, 6)]
a1, a2 = zip(*zip(a,b)) # 与 zip 相反,zip(*) 可理解为解压,返回二维矩阵式
list(a1)
<< [1, 2, 3]
list(a2)
<< [4, 5, 6]
lambda函数
使用lambda函数可以快速定义一个新函数:
f = lambda x, y: x*y # 定义f=f(x,y),函数输入是x和y,输出是它们的积x*y
#在使用f时,一定要写上传入函数
lambda:None # 函数没有输入参数,输出是None
lambda *args: sum(args) # 输入是任意个数参数,输出是它们的和(隐性要求输入参数必须能进行算术运算)
lambda **kwargs: 1 # 输入是任意键值对参数,输出是1
布尔变量的标记作用
例:找100以内质数
nums=[]
for num in range(2,101):
is_prime=True #布尔变量进行标记
#检验标记是否正确
for i in range(2,int(num**0.5+1)):
if num%i==0:
is_prime=False #检验失败
break
if is_prime: #检验通过
nums.append(num)
nums
2. numpy数组
import numpy as np
(1)array与ndarray
ndarray是一个类,其默认构造函数是ndarray()。而array是一个函数,便于创建一个ndarray对象。
A = np.array([[1,2,3],[4,5,6]])
A
<< array([[1, 2, 3],
[4, 5, 6]])
type(A)
<< numpy.ndarray
(2)基本操作
与Python自带的数组不同,numpy数组的操作都不是改变数组A自身,而是生成了一个新数组。
A.dtype #查看数据类型
<< dtype('int32')
A.shape #查看数组形状(行数,列数)
A.shape[0] #查看行数
A.shape[1] #查看列数
<< (2,3)
2
3
A.reshape(3,2) #数组变为x行y列
A.reshape(3,-1) #填-1后会自动计算行数或列数
A.reshape(-1) #变为1行
<<
array([[1, 2],
[3, 4],
[5, 6]])
array([[1, 2],
[3, 4],
[5, 6]])
array([1, 2, 3, 4, 5, 6])
B = np.array([[4,5,6]])
C = np.array([7,8,9])
np.hstack([B,C]) #A和B作为行向量拼接为一个数组,水平拓展
np.vstack([A,C]) #A和C作为行向量拼接为一个数组,竖直拓展
<<
array([[4,5,6,7,8,9]])
array([[4, 5, 6],
[7, 8, 9]])
np.row_stack([B,C]) #A和B作为行向量拼接为一个数组,竖直拓展,与np.vstack功能相同
np.column_stack([A,C]) #A和C作为列向量拼接为一个数组,水平拓展
<<
array([[4, 5, 6],
[7, 8, 9]])
array([[4, 7],
[5, 8],
[6, 9]])
A.swapaxes(0,1) #0、1轴互换,即得数组的转置
<<
array([[1, 4],
[2, 5],
[3, 6]])
A.sum() #对数组所有元素求和
A.sum(axis=0) #对元素逐列求和,返回只有一个轴的array(Python自带的sum函数无此功能)
<<
21
array([5, 7, 9])
A.max(axis=1) #沿1轴找每个0轴的最大值,返回只有一个轴的array(Python自带的max函数无此功能)
<< array([3, 6])
(3)切片操作
A[1,[0,2]] #返回第1行的0列和2列元素组成的array
<< array([4, 6])
A[1,1:3] #返回1行1到2列元素组成的array
<< array([5, 6])
A[-1,:] #返回最后一列的所有行元素组成的array
<< array([4, 5, 6])
#逐行打印出每一行(返回Python自带数组)
for i in range(A.shape[0])
print(A[i,:])
<<
[1 2 3]
[4 5 6]
(4)索引操作
A = [6,5,4]
list(enumerate(a)) #返回(索引,元素)
<<
[(0, 6), (1, 5), (2, 4)]
A = np.array([[6,5,4],[1,3,2]])
np.sort(A) #将数组的每一行都从小到大重排(不能用A.sort(),因为这种表达被Python自带sort函数占用)
np.sort(A,axis=1) #axis缺省为1,等同于np.sort(A)
np.sort(A,axis=0) #将数组的每一列都从小到大重排
<<
array([[4, 5, 6],
[1, 2, 3]])
array([[4, 5, 6],
[1, 2, 3]])
array([[1, 3, 2],
[6, 5, 4]])
np.argsort(A) #返回每一行各元素从小到大排列后对应的索引(axis同样缺省为1)
<<
array([[2, 1, 0],
[0, 2, 1]], dtype=int64)
#将数组按1行元素从小到大的顺序重排各列
args=np.argsort(A[1,:]) #1行各元素从小到大排列后对应的索引
A[:,args]
<<
array([[6, 4, 5],
[1, 2, 3]])
#返回1行最大值索引
A[1,:].argmax()
#或
A[1,:].argsort(-1)
<< 1
# where函数
np.where(A>4)|(A<3) #找到A中所有大于4和小于3的元素,返回索引
<<
(array([0, 0, 1, 1], dtype=int64), array([0, 1, 0, 2], dtype=int64)) #第一个数组是满足条件的0轴(行)索引,第二组是1轴(列)索引,一一对应,组成满足条件的坐标信息
# 将数组中所有的4换为1(对数组本身进行操作)
A[A==4]=0
A
<<
array([[6, 5, 0],
[1, 3, 2]])
(5)特殊矩阵
np.eye(3,dtype=int) #单位矩阵
<<
array([[1, 0, 0],
[0, 1, 0],
[0, 0, 1]])
np.ones((3,3),dtype=int) #全1矩阵
<<
array([[1, 1, 1],
[1, 1, 1],
[1, 1, 1]])
np.zeros((3,3),dtype=int) #全0矩阵
<<
array([[0, 0, 0],
[0, 0, 0],
[0, 0, 0]])
np.arange(1,4) #生成1到4不含4的一维数组
<< array([1, 2, 3])
np.arange(1,5).reshape(2,2) #生成1到5不含5的一维数组,再重整为2行2列矩阵
<<
array([[1, 2],
[3, 4]])
# 创建一个形状为(3, 3)且填充为 5 的数组
np.full((3, 3), 5)
<<
array([[5, 5, 5],
[5, 5, 5],
[5, 5, 5]])
(6)随机数组
np.random.random(10) #生成含10个0~1随机数组成的一维数组
<<
array([0.09473322, 0.93931516, 0.19075454, 0.24507363, 0.23257909, 0.79457509, 0.61654385, 0.73507355, 0.48250453, 0.15986826])
np.random.rand(2,4) #生成由0~1随机数组成的2乘4数组
<<
array([[0.32823175, 0.71639835, 0.21694984, 0.41437756],
[0.36511808, 0.95309061, 0.21356299, 0.88934674]])
np.random.randint(0,10,(2,2)) #生成范围从0到9的随机整数组成2乘2矩阵
<<
array([[9, 6],
[2, 6]])
np.random.uniform(0,10,(2,2)) #生成范围0到9的随机浮点数,满足均匀分布
<<
array([[4.74805249, 2.26723034],
[5.74314075, 4.56273036]])
np.random.normal(0,1,(2,2)) #生成满足期望为0,方差为1的正态分布的数组成的2乘2数组
<<
array([[-0.42962444, -2.27367562],
[ 0.35584446, -0.33776278]])
(7)线性代数
# A、B是矩阵,a、b是向量
np.matmul(A,B) #矩阵相乘
np.dot(a,b) #向量点积(不考虑复共轭)
np.dot(A,b) #矩阵与向量点乘(A矩阵乘b列向量或a行向量乘b列向量)
np.vdot(a,b) #向量点积(考虑复共轭,输入的矩阵将会被重塑为一维数组)
# 数组广播
# a为列向量,b为行向量,二者相乘构成一个矩阵
# 两个相同形状的数组每个元素相乘得到一个新数组
a*b
A*B
np.linlg.det(A) #行列式
np.linlg.inv(A) #逆矩阵
np.linlg.eig(A) #返回特征值组成的一维数组,和由每一行为特征向量组成的数组
3. matplotlib画图
import matplotlib.pyplot as plt
#防止中文乱码
plt.rcParams["font.sans-serif"]=["SimHei"] #设置字体
plt.rcParams["axes.unicode_minus"]=False #该语句解决图像中的“-”负号的乱码问题
(1)曲线图
matplotlib绘图基本步骤如下:
1.创建x轴点空间与y轴函数:
x = np.linspace(0,2*np.pi,1000) #(初值,末值,总点数)
y = np.sin(x)
2.创建绘图索引:
如:
fig, ax = plt.subplots()
或
fig, axs = plt.subplots(2,3,figsize=(6,8)) #fig是主图,axs是子图,有2行3列的子图,主图大小6*8
#axs是一个有2*3=6个元素的“数组”,每个元素都是一个子图,可以分别对子图进行操作
3.生成图像,并指定图像样式
ax.plot(x,y,label='sin(x)',lw=1,c=C, ls=LS, marker=M)
# (横坐标数据,纵坐标数据,图像标签,lw为线宽,颜色,线型,点型)
C=['m','g','orange','b','r','y','grey','k'] #颜色:分别代表紫、绿、橙、蓝、红、黄、灰、黑色
LS=['--',':'] #线型:缺省为实线,--为虚线,: 为点划线
M=['o','*','v','+','p','^','-','s'] #点型:分别为圆点、五角星、倒三角、十字、五边形、正三角、横杠、正方形
4.补全图表要素
#设置曲线图标题
ax.set_title('sin(x)曲线')
#设置坐标轴标题
ax.set_xlabel('x',fontsize=14) #fontsize指字体大小
ax.set_ylabel('y',fontsize=14)
#设置轴显示范围
ax.set_xlim(-1,4)
ax.set_ylim(-1.5,1.5)
#添加网格
ax.grid()
#添加图例
ax.legend(fontsize=10,frameon=False) #frameon=True有边框,frameon=False没边框
#展示刻度
ax.set_xticks(0.5,1,1.5,…)
ax.set_yticks([]) #去除刻度
#去除边框
ax.set_frame_on(False)
#设置x:y的缩放比例
ax.set_aspect(3,4)
#若有多个子图,可用这个函数摊开子图防止重叠
fig.tight_layout()
#展示图像
plt.show()
(2)直方图
ax.hist(y ,bins= ,label=' ',alpha= ,range=( , ),histtype=' ',lw= ,ls=' ')
#(直方图数据,区间数,标签,透明度(0到1),绘制的总区间范围,直方图类型('step'阶梯线),线宽,线型)
(3)散点图
ax.scatter(x,y,label=' ',marker=' ',s= ,c=' ')
#(横坐标数据,纵坐标数据,标签,点型,点大小,颜色)
(4)等高线图
例:绘制的等高线图,x和y的范围在(-3,3),取 levels = 10。
x=np.linspace(-3,3,50)
y=np.linspace(-3,3,50)
xy=np.meshgrid(x,y) #将x和y打包为网格,xy[0]为x轴,xy[1]为y轴
z = np.sqrt(xy[0]**2 + xy[1]**2 + (xy[0]-xy[1])**2)
fig, ax = plt.subplots()
ax.contour(x,y,z, levels=10)
(5)等高填充图\热力图
x=np.linspace(-3,3,100)
y=np.linspace(-3,3,100)
xy=np.meshgrid(x,y) #将x和y打包为网格,xy[0]为x轴,xy[1]为y轴
z = np.sqrt(xy[0]**2 + xy[1]**2 + (xy[0]-xy[1])**2)
fig, ax = plt.subplots()
ax.contourf(x,y,z, cmap=' ')
# cmap表示热力图样式,有'Reds', 'Greens', 'Blues', 'Oranges', 'spring', 'summer', 'autumn', 'winter','cool', 'hot', 'brg', 'rainbow'等