一.异常
语法错误(Syntax errors)
代码编译时的错误,不符合Python语言规则的代码会停止编译并返回 错误信息
异常(Exceptions)
相较于语法错误,异常比较难发现,因为它只在代码运行时才会发生, 如类型错 误、数值错误、索引错误和属性错误等。
语法错误:
1.缺少起始符号或结尾符号(括号、引号等)
2.缩进错误
3.关键词拼写错误
异常:
1.在定义函数之前就引用该函数
2.调用不属于某个对象的方法或者属性
3.试图将某个值转换为不恰当的数据类型
六种典型的异常
1.除零错误(ZeroDivisionError):除数为0
2.名称错误(NameError):变量使用前未进行申明或者初始化
3. 类型错误(TypeError):某些函数或者方法只适用于特定的数据类型,如果 对数据类型的操作不当,就会产生类型错误
4. 数值错误(ValueError):在输入类型正确的情况下,具体输入值错误
5.索引错误(IndexError):超出序列长度的索引操作
6.属性错误(AttributeError):方法或者属性不适用该对象
捕获异常
1.代码编写环境自带的高亮显示,便于发现常规语法错误,但难于发现异常
2.程序要遇到异常的时候,往往是直接中断,跳出执行。但是有些时候,我们需 要在遇到异常的时候另外处理,而不是直接停止。
解决办法:
1.try...except...语句
try关键词内执行的是正常代码,当这部分代码出错的时候,会跳过错误代 码后进入 except 关键词内部,执行此部分的代码
2.try...except...else语句
3. finally子句
finally语句是指,无论程序运行对或错,都会执行的部分
二.re模块函数
匹配单个字符:
(1)匹配单个数字:\d
(2)限制单个字符范围: []
(3)匹配单字符:\w
(4)匹配任意一个字符: .
匹配多个字符
匹配开头或结尾
匹配分组
import re
print(re.match(r"速度与激情\d", "速度与激情300").group()) # .group()将匹配到的内容取出来、[] 代表的是范围
print(re.match(r"数加科技[2-7]", "数加科技700"))
print(re.match(r"数加科技[abc123]", "数加科技zbc123"))
print(re.match(r"数加科技.", "数加科技7")) # 一个点代表的是匹配任意一个字符
print(re.match(r"数加科技.*", "数加科技")) # .* 表示任意一个字符会出现0次或者0次以上
print(re.match(r"数加科技.+", "数加科技e")) # .+ 表示任意一个字符会出现1次或者1次以上
print(re.match(r"数加科技.?", "数加科技")) # .? 表示任意一个字符会出现0次或者1次
print(re.match(r"数加科技.{3}", "数加科技qwer")) # {出现的次数} 限定要出现的次数
print(re.match(r"数加科技.{3,6}", "数加科技qwerty")) # {m,n} 表示匹配m-n次数
print(re.search(r"^a数加科技", "a数加科技123"))
print(re.search(r"a数加科技$", "123a数加科技"))
print(re.match(r"数加科技(ab|123)@(qq|163).com", "数加科技123@qq.com").group(2))
运行结果:
特殊字符
对于前面提到的所有用于匹配特殊字符,当要匹配它本身时,只需要在后面加上一个反斜杠:\ 特殊符号包含有:$ () * + . [ ? \ ^ { |
正则表达式修饰符 - 可选标志
re的使用
1.查找一个匹配项
查找并返回一个匹配项的函数有3个:search、match、fullmatch,他们的区别是:
-
search: 查找任意位置的匹配项
-
match: 必须从字符串开头匹配
-
fullmatch: 整个字符串与正则完全匹配
# match函数匹配是从字符串开头进行匹配
print(re.match(r"数加", "123数加456"))
# search函数匹配是任意位置匹配
print(re.search(r"数加", "123数加456"))
# fullmatch函数匹配的是整个字符串是否符合规则
print(re.fullmatch(r"^(13\d|14[5|7]|15[0|1|2|3|5|6|7|8|9]|18[0|1|2|3|5|6|7|8|9]|17\d)\d{8}$", "17376989014"))
运行结果:
2.查找多个匹配项
-
findall: 从字符串任意位置查找,返回一个列表
-
finditer:从字符串任意位置查找,返回一个迭代器
注:列表是一次性生成在内存中,而迭代器是需要使用时一点一点生成出来的,内存使用更优。
text = 's数加科技666,dsadsa数加科技66632131'
pattern = r"数加科技6{3}"
# # 查找所有匹配项,返回一个list
print("findall查找:", re.findall(pattern, text))
# 查找所有匹配项,返回一个迭代器
print("finditer查找:", len(list(re.finditer(pattern, text))))
运行结果:
3.分割
re.split(pattern, string, maxsplit=0, flags=0) 函数:用 pattern 分开 string , maxsplit表示最多进行分割次数
# # 使用正则进行切割:
text = 's数加科技666,j数加x科技666,x数加科技666'
print(text.split(","))#以,为分割标志
pattern = r"X"#以X为分割标志
print(re.split(pattern, text, maxsplit=2, flags=re.IGNORECASE))#IGNORECASE()函数:不区分大小写
运行结果:
4.替换
替换主要有sub函数 与 subn函数,他们功能类似!
先来看看sub函数的用法:
re.sub(pattern, repl, string, count=0, fl+
******ags=0) 函数参数讲解:repl替换掉string中被pattern匹配的字符, count表示最大替换次数,flags表示正则表达式的常量。
值得注意的是:sub函数中的入参:repl替换内容既可以是字符串,也可以是一个函数哦! 如果repl为函数时,只能有一个入参:Match匹配对象。
re.subn(pattern, repl, string, count=0, flags=0) 函数与 re.sub函数 功能一致,只不过返回一个元组 (字符串, 替换次数)。
text = '1数加科技666,2数加科技666,3数加科技666'
pattern = r","
repl = "|"
# 使用正则进行替换
print(re.sub(pattern, repl, text, count=1, flags=re.IGNORECASE))
print(re.subn(pattern, repl, text, flags=re.IGNORECASE))
运行结果:
五.编译正则对象
compile函数 与 template函数 将正则表达式的样式编译为一个 正则表达式对象 (正则对象Pattern),这个对象与re模块有同样的正则函数(后面我们会讲解Pattern正则对象)。
# 查找一个匹配象
text = '数加科技.确实*牛'
pattern = re.escape("数加科技.确实*牛")
# 查找任意位置
print(pattern)
print(re.search(pattern, text))
运行结果:
六.其他
re.escape(pattern) 可以转义正则表达式中具有特殊含义的字符,比如:
print('\n'),打印后的结果为遇到空格即换行;
手动转义后:
print("\\n"),打印输出后的结果为:\n
注意事项
Python 正则表达式知识基本讲解完毕,最后稍微给大家提一提需要注意的点。
1.字节串 与 字符串
模式和被搜索的字符串既可以是 Unicode 字符串 (str) ,也可以是8位字节串 (bytes)。 但是,Unicode 字符串与8位字节串不能混用!
2.r 的作用
正则表达式使用反斜杠(’’)来表示特殊形式,或者把特殊字符转义成普通字符。
而反斜杠在普通的 Python 字符串里也有相同的作用,所以就产生了冲突。
解决办法是对于正则表达式样式使用 Python 的原始字符串表示法;在带有 ‘r’ 前缀的字符串字面值中,反斜杠不必做任何特殊处理。
3.正则查找函数 返回匹配对象
查找一个匹配项(search、match、fullmatch)的函数返回值都是一个 匹配对象Match ,需要通过match.group() 获取匹配值,这个很容易忘记。 另外还需要注意:match.group() 与match.groups() 函数的差别!
-
group() 获取到的是匹配到的整体内容
-
groups() 获取到分组后的内容,以元组形式输出 示例:
4.重复使用某个正则
如果要重复使用某个正则表达式,推荐先使用 re.compile(pattern)函数 返回一个正则对象,然后复用这个正则对象,这样会更快!
三.numpy模块(矩阵)
几种 numpy 的属性
- ndim:维度
- shape:行数和列数
- size:元素个数
使用 numpy 首先要导入模块
import numpy as np #为了方便使用numpy 采用np简写
列表转化为矩阵
list1 = [[11, 22, 33], [44, 55, 66], [77, 88, 99]]
array1 = np.array(list1)
print(array1)
运行结果:
print('number of dim:', array1.ndim) # 维度
print('shape :', array1.shape) # 行数和列数
print('size:', array1.size) # 元素个数
运行结果:
Numpy 的创建 array
关键字
-
array:创建数组
-
dtype:指定数据类型
-
zeros:创建数据全为0
-
ones:创建数据全为1
-
empty:创建数据接近0
-
arrange:按指定范围创建数据
-
linspace:创建线段
import numpy as np
a = np.array([2, 23, 4]) # 创建一维数组
print('创建一维数组:')
print(a)
a = np.array([[2, 23, 4], [2, 32, 4]]) # 创建2d 矩阵 2行3列
print('创建2d 矩阵 2行3列:')
print(a)
a = np.zeros((3, 4)) # 创建全0数组,数据全为0,3行4列
print('全0数组,数据全为0,3行4列:')
print(a)
a = np.ones((3, 4)) # 创建全1数组,数据全为0,3行4列
print('创建全1数组,数据全为0,3行4列')
print(a)
a = np.empty((2, 4))
print('全空数组:')
print(a) # 创建全空数组, 其实每个值都是接近于零的数
a = np.arange(10, 20, 2) # 用 arange 创建连续数组,步长为2,区间10-20
print('用 arange 创建连续数组:')
print(a)
a = np.arange(12).reshape((3, 4)) # 使用 reshape 改变数据的形状,3行4列,
print('使用 reshape 改变数据的形状:')
print(a)
a = np.linspace(1, 10, 20) # 用 linspace 创建线段型数据,开始端1,结束端10,且分割成20个数据,生成线段
print('用 linspace 创建线段型数据')
print(a)
运行结果:
Numpy 的基础运算
加减乘
import numpy as np
a = np.array([10, 20, 30, 40]) # array([10, 20, 30, 40])
b = np.arange(4) # array([0, 1, 2, 3])
c=a+b #加
d=a-b #减
e=a*b #乘
print(c,d,e)
运行结果:
标准乘(矩阵乘法)
import numpy as np
a=np.array([[1,1],[0,1]])
b=np.arange(4).reshape((2,2))
c_dot1 = np.dot(a,b)#第一种表达方式
c_dot2 =a.dot(b)#第二种表达方式
print(c_dot1,'\n',c_dot2)#打印两次
运行结果:
关于 sum(), min(), max() 的使用
先定义一个脚本,因为是随机生成数字, 所以你的结果可能会不一样. 在第二行中对 a 的操作是令 a 中生成一个 2 行 4 列的矩阵,且每一元素均是来自从0到1的随机数。 在这个随机生成的矩阵中,我们可以对元素进行求和以及寻找极值的操作,具体如下:
import numpy as np
a=np.random.random((2,4))
print(a)
print(np.sum(a)) # 总和
print(np.min(a)) # 最小值
print(np.max(a)) # 最大值
运行结果:
矩阵相乘
两个矩阵只有当左边的矩阵的列数等于右边矩阵的行数时,两个矩阵才可以进行矩阵的乘法运算
e = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 0]])
f = np.array([[1, 2, 1], [1, 1, 2], [2, 1, 1]])
res_dot = np.dot(e, f)
print (res_dot)
运行结果:
常用方法
其中的 argmin() 和 argmax() 两个函数分别对应着求矩阵中最小元素和最大元素的索引。
mean(),average()对应求矩阵所有元素的均值 median()对应求中位数
另外,Numpy 中具有 cumsum() 函数,生成的每一项矩阵元素均是从原矩阵首项累加到对应项的元素之和
import numpy as np
A = np.arange(20).reshape((4, 5))
print(A)
print(np.mean(A))
print(np.average(A))
运行结果:
索引
一维索引
A[3]
二维索引
A[1,3:5]
合并
-
np.vstack() # vertical stack 上下合并
-
np.hstack() # horizontal stack 左右合并
-
np.newaxis() # 中转置操作
-
np.concatenate() # 多个合并
分割
A = np.arange(20).reshape((5, 4))
print(A)
print(np.array_split(A, 2, axis=0))#横向分割
print(np.array_split(A, 5, axis=1))#纵向分割
运行结果:
[[ 0 1 2 3]
[ 4 5 6 7]
[ 8 9 10 11]
[12 13 14 15]
[16 17 18 19]]
[array([[ 0, 1, 2, 3],
[ 4, 5, 6, 7],
[ 8, 9, 10, 11]]), array([[12, 13, 14, 15],
[16, 17, 18, 19]])]
[array([[ 0],
[ 4],
[ 8],
[12],
[16]]), array([[ 1],
[ 5],
[ 9],
[13],
[17]]), array([[ 2],
[ 6],
[10],
[14],
[18]]), array([[ 3],
[ 7],
[11],
[15],
[19]]), array([], shape=(5, 0), dtype=int32)]
注:必须为等量分割,否则会报错
不等量分割
在机器学习时经常会需要将数据做不等量的分割,因此解决办法为np.array_split()
成功将Array不等量分割
A = np.arange(20).reshape((5, 4))
print(np.array_split(A, 3, axis=1))
运行结果:
A = np.array([[1, 2, 3, 4], [11, 22, 33, 44], [12, 13, 14, 15]])
for i in A.flat:
print(i)
#一个一个输出所有元素