Python基础——Ch18~Ch2本文仅供学习使用
- 18. 正则表达式
- 18.1 re 模块
- 18.1.1 re.match 函数
- 18.1.2 re.search 方法
- 18.1.3 findall 函数
- 18.2 正则表达式模式
- 18.2.1 正则表达式中的字符
- 18.2.1.1 元字符
- 18.2.1.2 字符转义
- 18.2.1.3 开始与结束字符
- 18.2.2 字符类
- 18.2.2.1 定义字符类
- 18.2.2.2 字符类取反
- 18.2.2.3 区间
- 18.2.2.4 预定义字符类
- 18.3 量词
- 18.3.1 使用量词
- 18.3.2 贪婪量词和懒惰量词
- 18.4 分组
- 18.4.1 使用分组
- 18.4.2 命名分组
- 18.4.3 反向引用分组
- 18.4.4 非捕获分组
- 18.5 模式汇总
- 18.6 编译正则表达式
- 18.6.1 已编译正则表达式对象
- 18.6.2 编译标志
- 19. Python常用模块——NumPy
- 19.1 NumPy介绍
- 19.1.1 NumPy介绍NumPy历史:
- 19.1.2 NumPy模块:
- 19.1.3 NumPy核心数据结构:ndarray
- 19.2 ndarray
- 19.2.1 ndarray 的创建
- 19.2.2 属性
- 19.2.3 基本操作
- 19.2.4 索引和切片
18. 正则表达式
正则表达式是一个特殊的字符序列,它能帮助你方便的检查一个字符串是否与某种模式匹配。
re 模块使 Python 语言拥有全部的正则表达式功能。
compile 函数根据一个模式字符串和可选的标志参数生成一个正则表达式对象。该对象拥有一系列方法用于正则表达式匹配和替换。
re 模块也提供了与这些方法功能完全一致的函数,这些函数使用一个模式字符串做为它们的第一个参数。
正则表达式修饰符 - 可选标志:
正则表达式可以包含一些可选标志修饰符来控制匹配的模式。修饰符被指定为一个可选的标
志。多个标志可以通过按位 OR(|) 它们来指定。如 re.I | re.M 被设置成 I 和 M 标志:
Python的正则表达式模块re,有一个re.DOTALL的参数。默认情况下,正则表达式中的dot(.),表示所有除了换行的字符,加上re.DOTALL参数后,就是真正的所有字符了,包括换行符(n)
当使用re.MULTILINE时,^和$这两个符号的含义发生了一点变化,原来这两个符号表示整个字符串(可以有n换行符的字符串)的开始和结束,加上re.MULTILINE参数后,含义变为每行的开始和结束。re.M是这个参数的简写。
re.VERBOSE 或简写为 re.X:详细模式,可以在正则表达式中加注解!——允许为传入re.compile()的字符串添加空格和注释
18.1.1 re.match 函数18.1.2 re.search 方法re.match(pattern, string, flags=0)
re.match 尝试从字符串的起始位置匹配一个模式,如果不是起始位置匹配成功的话,match()就返回 none。
· pattern 匹配的正则表达式
· string 要匹配的字符串。
· flags 标志位,用于控制正则表达式的匹配方式,如:是否区分大小写,多行匹配等等。
· 匹配成功 re.match 方法返回一个匹配的对象,否则返回 None。
re.search(pattern, string, flags=0)
re.search 扫描整个字符串并返回第一个成功的匹配。
· pattern 匹配的正则表达式
· string 要匹配的字符串。
· flags 标志位,用于控制正则表达式的匹配方式,如:是否区分大小写,多行匹配等等。
· 匹配成功 re.match 方法返回一个匹配的对象,否则返回 None。
re.match 与 re.search 的区别:
re.match 只匹配字符串的开始,如果字符串开始不符合正则表达式,则匹配失败,函数返回
None;而 re.search 匹配整个字符串,直到找到一个匹配。
print(res) # 匹配
import re s = 'http://www.runoob.com.com' sub_s = '.' # . 代表任意字符,除了换行符 res = re.findall(sub_s, s) print(res) # ['h', 't', 't', 'p', ':', '/', '/', 'w', 'w', 'w', '.', 'r', 'u', 'n', 'o', 'o', 'b', '.', 'c', 'o', 'm', '.', 'c', 'o', 'm'] s = 'nhttp://www.runoob.com.com' res = re.match(sub_s, s) print(res) # None res = re.match(sub_s, s, re.S) # 可以使 . 匹配换行符 print(res) #18.1.3 findall 函数sub_s = '.' res = re.findall(sub_s, s) print(res) # ['.', '.', '.'] res = re.findall(sub_s, s)
findall(pattern, string[, pos[, endpos]])
在字符串中找到正则表达式所匹配的所有子串,并返回一个列表,如果没有找到匹配的,则返回空列表。
· pattern 匹配的正则表达式
· string : 待匹配的字符串。
· pos : 可选参数,指定字符串的起始位置,默认为 0。
· endpos : 可选参数,指定字符串的结束位置,默认为字符串的长度。
注意: match 和 search 是匹配一次, findall 匹配所有。
import re s = 'http://www.runoob.com.com' sub_s = 'com' res = re.findall(sub_s, s) print(res) # ['com', 'com']18.2 正则表达式模式 18.2.1 正则表达式中的字符
正则表达式是一种字符串,正则表达式字符串是由 普通字符串 和 元字符(Metacharacters) 组成。
普通字符:按照字符字面意义表示的字符、如 ② 所示,都表示字符本身的字面意义
元字符:预先定义好的一些特定字符,如 ① 所示
引号前加 r 的说明:
向 re.compile()传递原始字符串
回忆一下,Python中转义字符使用倒斜杠()。字符串’n’表示一个换行字符,而不是倒斜杠加上一个小写的n。你需要输入转义字符 \,才能打印出一个倒斜杠。所以’\n’表示一个倒斜杠加上一个小写的n。但是,通过在字符串的第一个引号之前加上r,可以将该字符串标记为原始字符串,它不包括转义字符。
因为正则表达式常常使用倒斜杠,向 re.compile((函数传入原始字符串就很方便,而不是输入额 外得到斜杠。输入r’ddd-ddd-dddd’,比 输入"\d\d\d-\d\d\d-\d\d\d\d’要容易得多。
元字符(Metacharacters) : 是用来描述其他字符的特殊字符,由 基本元字符 + 普通字符 构成
# 量词 import re s = 'http://www.runoob.com.com' sub_s = 't+' # 贪婪模式 res = re.search(sub_s, s) print(res) #18.2.1.2 字符转义sub_s = 'a+' # 重复1次或多次 res = re.search(sub_s, s) print(res) # None sub_s = 'a*' # 重复0次或多次 res = re.search(sub_s, s) print(res) # sub_s = 'h?' # 重复0次或1次 res = re.search(sub_s, s) print(res) # sub_s = 't+?' # 非贪婪模式 res = re.search(sub_s, s) print(res) # # sub_s = 't?+' # 不合法 # res = re.search(sub_s, s) # print(res) # baocuo s = 'ttpptttp' sub_s = 't??' # 第一个?为量词,第二个表示使用非贪婪模式 res = re.findall(sub_s, s) print(res) # ['', 't', '', 't', '', '', '', 't', '', 't', '', 't', '', ''] sub_s = 't*?' res = re.findall(sub_s, s) print(res) # ['', 't', '', 't', '', '', '', 't', '', 't', '', 't', '', ''] sub_s = '.*?' res = re.findall(sub_s, s) print(res) # ['', 't', '', 't', '', 'p', '', 'p', '', 't', '', 't', '', 't', '', 'p', ''] sub_s = '.??' res = re.findall(sub_s, s) print(res) # ['', 't', '', 't', '', 'p', '', 'p', '', 't', '', 't', '', 't', '', 'p', ''] ''' ?? 与 *? '''
不仅可以对普通字符进行转义,还可以对基本元字符进行转义。如域名中的点(.)字符希望按照点(.)字面意义使用,作为 .com 域名的一部分,而不是作为基本元字符使用,所以要加反斜杠“”进行转义。即‘ . ’。
import re s = 'http://www.runoob.com.com' sub_s = '.' # 代表任意字符,除了换行符 res = re.findall(sub_s, s) print(res) # ['h', 't', 't', 'p', ':', '/', '/', 'w', 'w', 'w', '.', 'r', 'u', 'n', 'o', 'o', 'b', '.', 'c', 'o', 'm', '.', 'c', 'o', 'm'] sub_s = '.' res = re.findall(sub_s, s) print(res) # ['.', '.', '.']18.2.1.3 开始与结束字符
当以^开始时,要求一行字符串的开始位置匹配;当以$结束时,要求一行字符串的结束位置匹配。所以正则表达式 w+@zhijieketang.com与 ^ w+@zhijieketang.com $ 是不同的
即:可以在正则表达式的开始处使用插入符号(^),表明匹配必须发生在被查找文本开始处。类似地,可以再正则表达式的末尾加上美元符号( $ ),表示该字符串必须以这个正则表达式的模式结束。可以同时使用^和$,表明整个字符串必须匹配该模式,也就是说,只匹配该字符串的某个子集是不够的。
^ 匹配字符串的开头
$ 匹配字符串的结尾
import re
email = r'koko@dlut.com'
m = re.search('dlut',email)
print(m) #
m = re.search('dlut$',email)
print(m) # None
m = re.search('^dlut','We know dlut is a school')
print(m) # None
m = re.search('^dlut$','dlut') # 整个字符串都要符合
print(m) #
import re rule = 't*' string = 'stt' res = re.findall(rule,string,re.I) print(res) # ['', 'tt', ''] res = re.fullmatch(rule,string,re.I) # 必须要全部符合,相当于 '^... $' print(res) # None18.2.2 字符类
正则表达式中可以使用字符类(Character class),一个字符类定义一组字符,其中的任一字符出现在输入字符串中即匹配成功。注意每次匹配只能匹配字符类中的一个字符。
18.2.2.1 定义字符类定义一个普通的字符类需要使用" [ “和” ] "元字符类。
18.2.2.2 字符类取反有时需要在正则表达式中指定不想出现的字符,可以在字符类前加“^”符号。
18.2.2.3 区间[…] 用来表示一组字符,单独列出:[amk] 匹配 ‘a’,‘m’或’k’
[^…] 不在[]中的字符:[^abc] 匹配除了 a,b,c 之外的字符。
区间是用连字符(-)表示的,[0123456789]采用区间表示为[0-9],[^ 0123456789]采用区间表示为[^0-9]。区间还可以表示连续的英文字母字符类,例如[a-z]表示所有小写字母字符类,[A-Z]表示所有大写字母字符类。
[A-Za-z0-9]表示所有因为字母和数值字符类,[0-25-7]表示0、1、2、5、6、7几个字符组成的字符类。
import re m = re.search(r'[A-Za-z0-9]','A10.3') print(m) #18.2.2.4 预定义字符类m = re.search(r'[0-7308]','A3489C') print(m) #
有些字符类很常用,例如[0-9]等,为了书写方便正则表达式提供了预定义的字符类,例如预定义字符类d等价于[0-9]字符类。
import re p = r'd' # [0-9] m = re.search(p, '1000') print(m) #18.3 量词 18.3.1 使用量词m = re.search(p, 'Pyhon 3') print(m) # m = re.search(p, 'A_你好Hello') print(m) # None p = r'w' # 任意语言的单词字符 数字 下划线 m = re.search(p, ' A_你好Hello') print(m) # #与量词结合 p = r'd+' # 任意语言的单词字符 数字 下划线 m = re.search(p, ' A_你好33Hello') print(m) # p = r'd{1}' # 任意语言的单词字符 数字 下划线 m = re.search(p, ' A_你好33Hello') print(m) #
量词是表示字符或者字符串重复的次数
量词还可以细分为贪婪量词和懒惰量词,贪婪量词会尽可能多地匹配字符,懒惰量词会尽可能少地匹配字符。大多数计算机语言的正则表达式量词默认是贪婪的,要想使用懒惰量词(非贪婪量词)可以在量词后面加"?"即可
18.4 分组在此之前学习量词只能重复显示一个字符,如果想让一个字符串作为整体使用量词,可将这个字符串放到一对小括号中,这就是分组(也称子表达式)。
18.4.1 使用分组对正则表达式进行分组不仅可以对一个字符串整体使用量词,还可以在正则表达式中引用已经存在的分组。
(re) 对正则表达式分组并记住匹配的文本
import re
p = r'wd{2}' # [0-9]
m = re.search(p, 'F1000_光轮')
print(m) #
p = r'(wd){2}' # [0-9]
m = re.search(p, 'F1000_光轮')
print(m) #
p = r'(0){2}' # [0-9]
m = re.search(p, 'F1000_光轮')
print(m) #
18.4.2 命名分组
在 Python 程序中访问分组时,除了可以通过组编号进行访问,还可以通过组名进行访问,前提是要在正则表达式中为组命名。组命名语法是在分组的左小括号后添加 ?P<分组名> 实现。
import re p = r'(w+).*1' m = re.search(p, 'title>abc18.4.3 反向引用分组p = r'(w+)d{3}1' m = re.search(p, 'title123title') print(m) # p = r'(w+).*1' m = re.search(p, 'title>123 m = re.search(p, 'aa>123) print(m) # m = re.findall(p, 'aa1123) print(m) # ['a1'] p = r'(wd)(123)' m = re.findall(p, 'aa1123) print(m) # [('a1', '123')] p = r'(?:wd)(?:123)' m = re.findall(p, 'aa1123) print(m) # ['a1123'] p = r'(d{3,4})-(d{7,8})' m = re.search(p, '0411-84708110') print(m.group(0)) # 0411-84708110 # 0 或者 空,表示获取匹配到的整个结果 print(m.group(1)) # 第一组 0411 print(m.group(2)) # 第二组 84708110 result = re.findall(r'(w+)=(d+)','set width=20 and height=10') print(result) # ['width=20', 'height=10'] result = re.search(r'(?P w+)=(1)','set width=width1 and height=height') print(result) # print(result.group('left')) # width
除了可以在程序代码中访问正则表达式匹配之后的分组内容,还可以在正则表达式内部引用之前的分组。
1…9 匹配第 n 个分组的内容。
10 匹配第 n 个分组的内容,如果它经匹配,否则指的是八进制字符码的表达式。
import re
result = re.findall(r'(w+)=(d+)','set width=20 and height=10')
print(result) # [('width', '20'), ('height', '10')]
result = re.findall(r'(?:w+)=(?:d+)','set width=20 and height=10')
print(result) # ['width=20', 'height=10']
result = re.findall(r'(w+)=(d+)','set width=20 and height=10')
print(result) # [('width', '20'), ('height', '10')]
result = re.findall(r'(w+)=(1)','set width=width1 and height=height')
print(result) # [('width', 'width'), ('height', 'height')]
'''
使用正则表达式将电话号码13811119999变成138****9999
'''
str1 = '13811119999'
p = r'(d{3})(d{4})(d{3})'
print(re.sub(p,r'1****3',str1)) # 引用分组
18.4.4 非捕获分组
前面介绍的分组称为捕获分组,就是匹配子表达式结果被暂时保存到内存中,以备表达式或其他程序引用,这称之为"捕获",捕获结果可以通过组编号或组名进行引用。但是有时并不想引用子表达式的匹配结果,不想捕获匹配结果,只是将小括号作为一个整体进行匹配,此时可以使用非捕获分组,非捕获分组在组开头使用"?∶"实现。
p = r'(d{3,4})-(d{7,8})'
m = re.findall(p, '0411-84708110')
print(m) # [('0411', '84708110')]
p = r'(?:d{3,4})-(?:d{7,8})'
m = re.findall(p, '0411-84708110')
print(m) # ['0411-84708110']
# print(m.group(1)) # baocuo
注意:作为 findall()方法的返回结果的总结,请记住下面两点:
- 如果调用在一个没有分组的正则表达式上,例如ddd-ddd-dddd,方法 findall()将返回一个匹配字符串的列表,例如[‘415-555-9999’, ‘212-555-0000’]。
- 如果调用在一个有分组的正则表达式上,例如(ddd)-(ddd)-(dddd),方法 findall()将
返回一个字符串的元组的列表(每个分组对应一个字符串),例如[(‘415’, ‘555’, ‘1122’), (‘212’,
‘555’, ‘0000’)]。
18.5 模式汇总phoneNumRegex.findall(‘Cell: 415-555-9999 Work: 212-555-0000’)
中文正则模式[u4E00-u9FA5]
'''
使用正则表达式将字符串中的标点符号、数字和字母删除
string=”据悉,这次发运的4台蒸汽冷凝罐属于国际热核聚变实验堆(ITER)项目的核二级压力设备,先后完成了压力试验、真空试验、氦气检漏试验、千斤顶试验、吊耳载荷试验、叠装试验等验收试验。”
'''
# string = '据悉,这次发运的4台蒸汽冷凝罐属于国际热核聚变实验堆(ITER)项目的核二级压力设备,先后完成了压力试验、真空试验、氦气检漏试验、千斤顶试验、吊耳载荷试验、叠装试验等验收试验。'
# p = r'[,()、。0-9a-zA-Z]'
# print(re.sub(p, '', string))
string = '据悉,这次发运的4台蒸汽冷凝罐属于国际热核聚变实验堆(ITER)项目的核二级压力设备,先后完成了压力试验、真空试验、氦气检漏试验、千斤顶试验、吊耳载荷试验、叠装试验等验收试验。'
p = r'[^u4E00-u9FA5]'
print(re.sub(p, '', string))
'''
判断以下字符是否全是中文(中文正则模式[u4E00-u9FA5])
str='广东省广州市'
'''
# p = r'^[u4E00-u9FA5]$'
# str='广东省广州市'
# print(re.findall(p, str))
string='广东省广州市'
pattern = r'[u4E00-u9FA5]'
sub_str = re.sub(pattern, '', string)
result = False
if not sub_str:
result = True
print('%s是否是中文的结果:%s'%(string, result))
18.6 编译正则表达式
但是为了提高效率,还可以对Python 正则表达式进行编译。编译的正则表达式可以重复使用,减少正则表达式解析和验证,提高效率。
在 re模块中的compile() 函数可以编译正则表达式,compile() 函数语法如下∶
18.6.1 已编译正则表达式对象re.compile(pattern[, flags=0])
regex.sub
(function)
sub(pattern: str | Pattern[str], repl: str | ((Match[str]) -> str), string: str, count: int = …, flags: _FlagsType = …) -> str
返回通过替换 repl 替换字符串中最左侧的模式的非重叠实例而获得的字符串。repl 可以是字符串,也可以是可调用的;如果字符串,则处理其中的反斜杠转义。如果它是可调用的,则它传递 Match 对象,并且必须返回要使用的替换字符串。
import re
p = r'(d{3,4})-(d{7,8})'
m = '0411-84708110'
regx = re.compile(p) # 表达式重复编译的次数较多,可以提前编译成一个对象,再使用
regx.search(m)
result = re.findall(r'(w+)=(d+)','set width=20 and height=10')
print(result) # [('width', '20'), ('height', '10')]
result = re.findall(r'(?:w+)=(?:d+)','set width=20 and height=10')
print(result) # ['width=20', 'height=10']
18.6.2 编译标志
compile() 函数编译正则表达式对象时,还可以设置编译标志。编译标志可以改变正则表达式引擎行为。本节详细介绍几个常用的编译标志。
- ASCII和 Unicode
- 忽略大小写
- 点(.)元字符匹配换行符
- 多行模式
- 详细模式
NumPy、Scipy、pandas、matplotlib简介:
NumPy(Numerical Python) 是 Python 语言的一个扩展程序库,支持大量的维度数组与矩阵运算,此外也针对数组运算提供大量的数学函数库。
numPy 的前身 Numeric 最早是由 Jim Hugunin 与其它协作者共同开发,2005 年,Travis Oliphant 在 Numeric 中结合了另一个同性质的程序库 Numarray 的特色,并加入了其它扩展 而开发了 NumPy。NumPy 为开放源代码并且由许多协作者共同维护开发。
NumPy 是一个运行速度非常快的数学库,主要用于数组计算,包含:
• 一个强大的N维数组对象 ndarray
• 广播功能函数
• 整合 C/C++/Fortran 代码的工具
• 线性代数、傅里叶变换、随机数生成等功能
• 1995年Jim HugUNin开发了Numeric
• 随后Numarray包诞生
• Travis Oliphants整合Numeric和Numarray,开发NumPy,2006 年第一个版本诞生
• 使用Anaconda发行版的Python,已经安装好NumPy模块,所以可以不用再安装NumPy模块了。
• 依照标准的NumPy标准,习惯使用import numpy as np的方式导入该模块。
Numerical Python,即数值Python包,是Python进行科学计算的一个基础包,所以是一个掌握 其他Scipy库中模块的基础模块,一定需要先掌握该包的主要使用方式。
安装: pip install numpy scipy matplotlib
NumPy 最重要的一个特点是其 N 维数组对象 ndarray,它是一系列同类型数据的集合,以 0 下标为开始进行集合中元素的索引。 ndarray 对象是用于存放同类型元素的多维数组。ndarray 中的每个元素在内存中都有相同存储大小的区域。
19.2 ndarrayndarray 内部由以下内容组成:
- 一个指向数据(内存或内存映射文件中的一块数据)的指针。
- 数据类型或 dtype,描述在数组中的固定大小 值的格子。
- 一个表示数组形状(shape)的元组,表示各维度大小的元组。
- 一个跨度元组(stride),其中的整数指的是为了前进到当前维度下一个元素需要"跨过"的字节数
NumPy 的数组中比较重要 ndarray 对象属性有:
| 对象属性 | 说明 |
|---|---|
| ndarray.ndim | 秩(弱的概念),即轴的数量或维度的数量 |
| ndarray.shape | 数组的维度,对于矩阵,n 行 m 列 |
| ndarray.size | 数组元素的总个数,相当于 .shape 中 n*m 的值 |
| ndarray.dtype | ndarray对象的元素类型 |
| ndarray.itemsize | ndarray对象中每个元素的大小,以字节为单位 |
| ndarray.flags | ndarray对象的内存信息 |
| ndarray.real | ndarray元素的实部 |
| ndarray.imag | ndarray元素的虚部 |
| ndarray.data | 包含实际数组元素的缓冲区,由于一般通过数组的索引获取元素,所以通常不 需要使用这个属性。 |
import numpy as np a = np.array([[1,2,3],[4,5,6]]) print (a.ndim) # 2 print (a.shape) # (2, 3) print (a.size) # 6 # 数组的 dtype 为 int8(一个字节) x = np.array([1,2,3,4,5], dtype = np.int8) print (x.itemsize) # 1 # 数组的 dtype 现在为 float64(八个字节) y = np.array([1,2,3,4,5], dtype = np.float64) print (y.itemsize) # 819.2.1 ndarray 的创建
- 使用列表创建
import numpy as np lis = [1, 2, 3] lis2 = [[1, 2, 3], [1, 2, 3]] arr1 = np.array(lis) arr2 = np.array(lis2) print(type(arr1)) #print('arr1:', arr1) # arr1: [1 2 3] print('arr2:', arr2) # arr2: [[1 2 3] [1 2 3]] a = np.array([[1, 2], [3, 4]]) print (a) ''' [[1 2] [3 4]] ''' print (a.itemsize,a.dtype) # 4 int32 a = a.astype(np.float64) print (a.itemsize,a.dtype) # 8 float64
- 快速创建
np.empty(size -> tuple, [dtype])
返回给定形状和类型的新数组,而不初始化条目。
arange函数: 类似python的range函数,通过指定开始值、终值和步长来创建一个一维数组,注意:最终创 建的数组不包含终值
import numpy as np
# 快速创建
arr1 = np.ones((3, 3)) # 全1 传入元组
arr2 = np.zeros((3, 3)) # 全0 传入元组
arr3 = np.eye(4) # 4*4的单位矩阵 传入int
arr4 = np.arange(9) # 创建一个一维数组
arr5 = np.arange(9).reshape(3,-1) # 创建一个一维数组
print('arr1:', arr1)
print('arr2:', arr2)
print('arr3:', arr3)
print('arr4:', arr4)
print('arr5:', arr5)
'''
arr1: [[1. 1. 1.]
[1. 1. 1.]
[1. 1. 1.]]
arr2: [[0. 0. 0.]
[0. 0. 0.]
[0. 0. 0.]]
arr3: [[1. 0. 0. 0.]
[0. 1. 0. 0.]
[0. 0. 1. 0.]
[0. 0. 0. 1.]]
arr4: [0 1 2 3 4 5 6 7 8]
arr5: [[0 1 2]
[3 4 5]
[6 7 8]]
'''
x = np.empty((3,2), dtype = int)
print (x)
'''
[[1599229779 1163281740]
[ 3554636 1129271888]
[1330860869 1163026258]]
'''
y = np.zeros((5,), dtype = int)
print (y) # [0 0 0 0 0]
x = np.ones([1,2], dtype = int)
print (x) # [[1 1]]
b = [(1,2,3),(4,5)]
a = np.asarray(b) # 不推荐——VisibleDeprecationWarning
print (a) # [(1, 2, 3) (4, 5)]
print(np.asarray([1, 2, 3, 4]).reshape((2,2)) )
'''[[1 2]
[3 4]]'''
x = np.arange(5, dtype = float)
print(x) # [0. 1. 2. 3. 4.]
- 其他方式:
linspace函数:通过指定开始值、终值和元素个数来创建一个一维数组,数组的数据元素符合等差数列,可 以通过endpoint关键字指定是否包含终值,默认包含终值
logspace函数:和linspace函数类似,不过创建的是等比数列数组
使用随机数填充数组,即使用numpy.random中的random()函数来创建0-1之间的随机元素,数组包含的元素数量由参数决定
import numpy as np print(np.linspace(1,10,10, dtype = int)) # [ 1 2 3 4 5 6 7 8 9 10] print(np.logspace(1,5,5, dtype = int)) # 10**1 ~ 10**5 的等比数列 [ 10 100 1000 10000 100000] print(np.logspace(1,5,5,base = 2, dtype = int)) # 2**1 ~ 2**5 的等比数列 [ 2 4 8 16 32] print(np.random.random((5,))) # [0.41314034 0.40066512 0.07242052 0.96087116 0.66801133] 指定数组大小19.2.2 属性
import numpy as np
lis = [1, 2, 3]
lis2 = [[1, 2, 3], [1, 2, 3]]
arr1 = np.array(lis)
arr2 = np.array(lis2)
print('arr1.shape:', arr1.shape) # (3,)
print('arr2.shape:', arr2.shape) # (2, 3)
# 形状:元组,元组的元素个数代表数组的维数,元素数值的大小代表该维度数组的个数
print(arr2.size) # 数组的大小,一共多少个元素,等于shape所有元素的乘积。
print(arr2.ndim) # 2 与数学上的秩概念不完全相同
print(arr2.dtype) # int32
19.2.3 基本操作
- 改变形状reshape(),参数:tuple or int
对于一个已经存在的ndarray数组对象而言,可以通过修改形状相关的参数/方法从而改 变数组的形状。
· 直接修改数组ndarray的shape值, 要求修改后乘积不变。
· 直接使用reshape函数创建一个改变尺寸的新数组,原数组的shape保持不变,但是 新数组和原数组共享一个内存空间,也就是修改任何一个数组中的值都会对另外一个 产生影响,另外要求新数组的元素个数和原数组一致。
import numpy as np
lis = [1, 2, 3]
lis2 = [[1, 2, 3], [1, 2, 3]]
arr1 = np.array(lis)
arr2 = np.array(lis2)
# 数组的size得相同
new_shape = (3, 2)
arr3 = arr2.reshape(new_shape)# 参数:tuple
arr4 = arr2.reshape(1, 6) # 参数是多个int
# arr5 = arr2.reshape(1, 3)# 不可以,数组的size得相同
arr6 = arr2.reshape(1, -1)# -1表示自动算该轴/维度的元素个数,此时-1代表6
arr7 = arr2.reshape(1, 2, -1)# -1代表3
print('arr3:', arr3)
print('arr4:', arr4)
print('arr6.shape:', arr6.shape)
print('arr7.shape:', arr7.shape)
print('arr6:', arr6)
print('arr7:', arr7)
'''
arr3: [[1 2]
[3 1]
[2 3]]
arr4: [[1 2 3 1 2 3]]
arr6.shape: (1, 6)
arr7.shape: (1, 2, 3)
'''
- 改变数据类型astype(np.dtype)
创建numpy数组的时候可以通过属性dtype显示指定数据类型,如果不指定的情况下,numpy会自动推断出 适合的数据类型,所以一般不需要显示给定数据类型。
如果需要更改一个已经存在的数组的数据类型,可以通过astype方法进行修改从而得到一个新数组。
import numpy as np lis = [1, 2, 3] lis2 = [[1, 2, 3], [1, 2, 3]] arr1 = np.array(lis) arr2 = np.array(lis2) arr8 = arr2.astype(np.float32) print(arr2.dtype) # int32 print(arr8.dtype) # float32
可改变的类型
| 数据类型 | 说明 |
|---|---|
| bool_ | 布尔型数据类型(True 或者 False) |
| int_ | 默认的整数类型(类似于 C 语言中的 long,int32 或 int64) |
| intc | 与 C 的 int 类型一样,一般是 int32 或 int 64 intp 用于索引的整数类型(类似于 C 的 ssize_t,一般情况下仍然是 int32 或 int64) |
| int8 | 字节(-128 to 127) |
| int16 | 整数(-32768 to 32767) |
| int32 | 整数(-2147483648 to 2147483647) |
| int64 | 整数(-9223372036854775808 to 9223372036854775807) |
| uint8 | 无符号整数(0 to 255) |
| uint16 | 无符号整数(0 to 65535) |
| uint32 | 无符号整数(0 to 4294967295) |
| uint64 | 无符号整数(0 to 18446744073709551615) |
| float_ | float64 类型的简写 float16 半精度浮点数,包括:1 个符号位,5 个指数位,10 个尾数位 |
| float64 | 双精度浮点数,包括:1 个符号位,11 |
import numpy as np
arr1 = np.arange(9)# 创建一个一维数组
print('1', arr1[0]) # 0
print('1', arr1[1]) # 1
print('1', arr1[0:5]) # [0 1 2 3 4]
print('1', arr1[0:]) # [0 1 2 3 4 5 6 7 8]
print('1', arr1[:]) # [0 1 2 3 4 5 6 7 8]
print('1', arr1[1:4]) # [1 2 3]
print('1', arr1[1:4:2])# 步长为2 # [1 3]
#轴1
arr2 = np.arange(9).reshape((3,3))# 创建一个二维数组
print('2:', arr2)
print('2:', arr2[0]) # 0轴
'''
[[0 1 2]
[3 4 5]
[6 7 8]]
'''
print('2:', arr2[1]) # 1轴 [0 1 2]
print('2:', arr2[2]) # 2轴 [3 4 5]
print('2:', arr2[0:]) # quanbu
print('2:', arr2[:]) # quanbu
print('2:', arr2[1:2])
'''
[[3 4 5]
[6 7 8]]
'''
print('2:', arr2[0:4:2])# 步长为2
'''
[[0 1 2]
[6 7 8]]
'''
# 多维度切片—— # 轴1 + 轴2
print('3:', arr2[:, 0:1]) # 分别对各个维度进行切片 常用
'''
[[0]
[3]
[6]]
'''
print('3:', arr2[1:3, 1:3]) # [[4, 5],[7 ,8]]
print('3:', arr2[0:1, 0:1]) # 等维度的切片不降维 常用 [[0]]
print('3:', arr2[0:1, 0]) # int索引会降维 [0]
print('3:', arr2[0, 0]) # int索引会降维 0
print('3:', arr2[0, 0:1]) # int索引会降维 [0]
# 多维度索引—— # 轴1 + 轴2
print('4:', arr2[0, 0])# 0
print('4:', arr2[1, 2])# 5
数组索引:
import numpy as np
arr2 = np.arange(9).reshape((3,3))# 创建一个二维数组
print('1:', arr2[[1,0,2]])
'''
1: [[3 4 5]
[0 1 2]
[6 7 8]]
'''
print('1:', arr2[[0,1,2],[0,1,2]]) # 1: [0 4 8]
print('1:', arr2[[0,1,2],0]) # 1: [0 3 6] 广播 [[0, 1, 2], [0, 0, 0]]
print('1:', arr2[1,[0,1,2]]) # 1: [3 4 5] 广播 [[0,0,0], [0, 1, 2]]
# print(arr4[[0, 1, 2], [0, 1]])# 无法广播 with shapes (3,) (2,)
广播:
广播机制:为了解决两个数组在进行对应元素的操作时,即使形状不同也可以操作
广播的规则:
- 维度不同时,最高维为输出的最终维度
- 不够最终维度的数组,要往前面扩维度
- 同维度的元素个数,要么相同,要么其中一个为1,那就可以进行广播,否则就不可以,广播的时候,为1的将复制。
(2,3) 与(3,) 扩充维度-> (1, 3) 复制->(2, 3)
(3, )与(2, ) 不可以
(2, 3)与(2,) 不可以
快速判断能否广播:
- 看形状:从右往左看而且只需要看最短的
- 对应位置的元素要么相同,要么其中一个为1
(2,3,5,7) 与 (5,7) 可以
(2,3,5,7) 与 (5,) 不可以
(5,7)与(7,5) 不可以
(1,7)与(7,1) 可以
(2,3) 与 0 可以,任何形状跟标量都可以
import numpy as np # 对应元素的运算,也会有广播机制 arr6_1 = np.arange(210).reshape(2,3,5,7) arr6_2 = np.arange(35).reshape(5,7) print(arr6_1 + arr6_2) arr7_1 = np.arange(210).reshape(2,3,5,7) arr7_2 = np.arange(5) # print(arr7_1 - arr7_2)# could not be broadcast together with shapes (2,3,5,7) (5,) arr8_1 = np.arange(35).reshape(5, 7) arr8_2 = np.arange(35).reshape(7, 5) # print(arr8_1 * arr8_2)# could not be broadcast together with shapes (5,7) (7,5) arr9_1 = np.arange(7).reshape(1, 7) print(arr9_1) arr9_2 = np.arange(7).reshape(7, 1) #print(arr9_2) print(arr9_1 + arr9_2) ''' [[ 0 1 2 3 4 5 6] [ 1 2 3 4 5 6 7] [ 2 3 4 5 6 7 8] [ 3 4 5 6 7 8 9] [ 4 5 6 7 8 9 10] [ 5 6 7 8 9 10 11] [ 6 7 8 9 10 11 12]] ''' arr910_1 = 1 print(arr9_1+arr910_1)
# 切片+数组 import numpy as np arr4 = np.arange(9).reshape((3,3))# 创建一个二维数组 print(arr4[:, [0]])# 维度不变 [[0] [3] [6]] 常用 print(arr4[:, 0])# 降维 [0 3 6] print(arr4[:, [1, 0]]) ''' [[1 0] [4 3] [7 6]] ''' print(arr4[[0, 1, 2], [0]])# [arr4[0][0] ,arr4[1][0] , arr4[2][0]] [0 3 6]


![[深度学习]Part1 Python学习基础Ch18~Ch2——【DeepBlue学习笔记】 [深度学习]Part1 Python学习基础Ch18~Ch2——【DeepBlue学习笔记】](http://www.mshxw.com/aiimages/31/921193.png)
