前言
在18年的时候就把python的基本语法过了一遍了,无奈matlab和mathematica太好用了,所以python这个工具就一直被我给冷落了,现在重新拾起。文中的内容,有些是书本里面的,有些源自于菜鸟教程和一些零散的博客所汇聚而成,仅供自己学习和参考使用。
基础知识
以下划线开头的标识符是有特殊意义的。以单下划线开头 _foo 的代表不能直接访问的类属性,需通过类提供的接口进行访问,不能用 from xxx import * 而导入。 以双下划线开头的__foo 代表类的私有成员,以双下划线开头和结尾的 __foo__ 代表 Python 里特殊方法专用的标识,如 __init__() 代表类的构造函数。
if __name__ == ‘__main__‘的意思是:当.py文件被直接运行时,if __name__ == ‘__main__‘之下的代码块将被运行;当.py文件以模块形式被导入时,if __name__ == ‘__main__‘之下的代码块不被运行。
对程序计时可用如下两种方式:
1)time.time() 返回的是一个浮点型类型。这里获取的也是程序的执行时间。使用方法如下所示
start = time.time()
#^_^
end = time.time()
print (end-start)2) time.clock()返回程序开始或第一次被调用clock()以来的CPU时间。这里获得的是CPU的执行时间。调用方式只需要把time.time()换成 time.clock()即可。
读取文件
读取文件夹下所有的文件
import os |
序列函数
enumerate函数
迭代一个序列时,你可能想跟踪当前项的序号。手动的方法可能是下面这样:
i = 0 |
因为这么做很常见,Python内建了一个 enumerate 函数,可以返回 (i, value) 元组序列:
for i, value in enumerate(collection): |
当你索引数据时,使用 enumerate 的一个好方法是计算序列(唯一的) dict 映射到位置的值。
zip函数
zip 可以将多个列表、元组或其它序列成对组合成一个元组列表。zip 可以处理任意多的序列,元素的个数取决于最短的序列。zip 的常见用法之一是同时迭代多个序列,可以结合 enumerate 使用:
for i, (a, b) in enumerate(zip(seq1, seq2)): |
字典
字典可能是Python最为重要的数据结构。它更为常见的名字是哈希映射或关联数组。它是键值对的大小可变集合,键和值都是Python对象。创建字典的方法之一是使用大括号,用冒号分隔键和值:
empty_dict = {} |
可以像访问列表或元组中的元素一样,访问、插入或设定字典中的元素,也可以用检查列表和元组是否包含某个值的方法,检查字典中是否包含某个键。keys 和 values 是字典的键和值的迭代器方法。虽然键值对没有顺序,这两个方法可以用相同的顺序输出键和值:用 update 方法可以将一个字典与另一个融合:
d1.update({'b' : 'foo', 'c' : 12}) |
update 方法是原地改变字典,因此任何传递给 update 的键的旧的值都会被舍弃。
用序列创建字典
可能想将两个序列配对组合成字典。下面是一种写法:
mapping = {} |
因为字典本质上是2元元组的集合,dict可以接受2元元组的列表:
mapping = dict(zip(range(5), reversed(range(5)))) |
下面的逻辑很常见:
if key in some_dict: |
因此,dict的方法get和pop可以取默认值进行返回,上面的if-else语句可以简写成下面:
value = some_dict.get(key, default_value) |
有效的键类型
字典的值可以是任意Python 对象,而键通常是不可变的标量类型(整数、浮点型、字符串)或元组(元组中的对象必须是不可变的)。这被称为“可哈希性”。可以用 hash 函数检测一个对象是否是可哈希的。 要用列表当做键,一种方法是将列表转化为元组,只要内部元素可以被哈希,它也就可以被哈希。
集合
集合是无序的不可重复的元素的集合。可以把它当做字典,但是只有键没有值。可以用两种方式创建集合:通过 set 函数或使用尖括号 set 语句.集合支持合并、交集、差分和对称差等数学集合运算. 合并是取两个集合中不重复的元素。可以用 union 方法,或者运算符|.交集的元素包含在两个集合中。可以用 intersection 或&运算符.所有逻辑集合操作都有另外的原地实现方法,可以直接用结果替代集合的内容。对于大的集合,这么做效率更高.与字典类似,集合元素通常都是不可变的。要获得类似列表的元素,必须转换成元组.
列表、集合和字典推导式
列表推导式允许用户方便的从一个集合过滤元素,形成列表在传递参数的过程中还可以修改元素。形式如下
[expr for val in collection if condition] |
它等同于下面的 for 循环:
result = [ ] |
用相似的方法,还可以推导集合和字典。字典的推导式如下所示dic = {key: value-expr for value in collection if condition}
集合的推导式与列表很像,只不过用的是尖括号
set_comp = {expr for value in collection if condition} |
与列表推导式类似,集合与字典的推导也很方便,而且使代码的读写都很容易。来看前面的字符串列表。假如我们只想要字符串的长度,用集合推导式的方法非常方便.
Python 合并字典
1,使用 update()
方法,第二个参数合并第一个参数
def Merge(dict1, dict2): |
2, 使用 **
, 函数将参数以字典的形式导入
def Merge(dict1, dict2): |
函数
函数使用 def 关键字声明,用 return 关键字返回值,如果到达函数末尾时没有遇到任何一条return语句,则返回 None。 函数可以有一些位置参数(positional)和一些关键字参数(keyword)。关键字参数通常用于指定 默认值或可选参数。
命名空间、作用域
函数可以访问两种不同作用域中的变量:全局(global)和局部(local)。任何在函数中赋值的变量默认都是被分配到局部命名空间(local namespace)中的。局部命名空间是在函数被调用时创建的,函数参数会立即填入该命名空间。在函数执行完毕之后,局部命名空间就会被销毁
生成器
能以一种一致的方式对序列进行迭代(比如列表中的对象或文件中的行)。通过一种叫做迭代器协议 iterator protocol,它是一种使对象可迭代的通用方式)的方式实现的,一个原生的使对象可迭代的方法。生成器(generator)是构造新的迭代对象的一种简单方式。一般的函数执行之后只会返回单个值,而生成器则是以延退的方式返回一个值序列,即每返回一个值之后暂停,直到下一个值被请求时再继续。要创建一个生成器,只需将函数中的 return 替换为 yeild 即可。调用该生成器时,没有任何代码会被立即执行。直到请求元素时,它オ会开始执行其代码。
生成器表达式
另一种更简洁的构造生成器的方法是使用生成器表达式(generator expression)。这是一种类似于列表、字典、集合推导式的生成器。其创建方式为,把列表推导式两端的方括号改成圆括号。
python字符串前面加u,r,b的含义
u/U:表示unicode字符串
。不是仅仅是针对中文, 可以针对任何的字符串,代表是对字符串进行unicode编码。一般英文字符在使用各种编码下, 基本都可以正常解析, 所以一般不带u;但是中文, 必须表明所需编码, 否则一旦编码转换就会出现乱码。
建议所有编码方式采用utf8
r/R:非转义的原始字符串
。与普通字符相比,其他相对特殊的字符,其中可能包含转义字符,即那些,反斜杠加上对应字母,表示对应的特殊含义的,比如最常见的”\n”表示换行,”\t”表示Tab等。而如果是以r开头,那么说明后面的字符,都是普通的字符了,即如果是“\n”那么表示一个反斜杠字符,一个字母n,而不是表示换行了。以r开头的字符,常用于正则表达式,对应着re模块。
b:bytes
。python3.x里默认的str是(py2.x里的)unicode, bytes是(py2.x)的str, b”“前缀代表的就是bytespython2.x里, b前缀没什么具体意义, 只是为了兼容python3.x的这种写法。
文件和操作系统
为了打开一个文件以便读写,可以使用内置的open函数以及一个相对或绝对的文件路径。从文件中取出的行都带有完整的行结束符(EOL),因此你常常会看到下面这样的代码(得到一组没有EOL的行):
lines = [x.rstrip() for x in open(path)] |
如果使用open创建文件对象,一定要用close关闭它。关闭文件可以返回操作系统资源:
f.close() |
用with语句可以可以更容易地清理打开的文件:
with open (path) as f: |
这样可以在退出代码块时,自动关闭文件。向文件写入,可以使用文件的write或writelines方法。例如,创建一个无空行版的
with open('tmp.txt','w') as handle: |
最常用的文件方法如下表所示:
方法 | 说明 |
---|---|
read([size]) | 以字符串形式返回文件数据,可选的size参数用于说明读取的字节数 |
readlines([size]) | 将文件返回为行列表,可选参数size |
write(str) | 将字符串写入文件 |
close() | 关闭句柄 |
flush() | 清空内部I/O缓存区,并将数据强行写回磁盘 |
seek(pos) | 移动到指定的文件位置(整数) |
tell | 以整数形式返回当前文件位置 |
closed() | 如果文件已关闭,则为True |
一种更方便的方法将Unicode转换为另一种编码:
sink_path = 'sink.txt' |
注意,不要在二进制模式中使用seek。如果文件位置位于定义Unicode字符的字节的中间位置,读取后面会产生错误.
python文件打开方式
r只读,r+读写,不创建新的文件,w新建文件只写入,w+新建读写,二者都会将文件内容清零。r+:可读可写,若文件不存在,则报错;w+: 可读可写,若文件不存在,则创建一个新的文件。a:附加写方式打开,不可读;a+: 附加读写方式打开。使用’r’一般情况下最常用的,但是在进行读取二进制文件时,可能会出现文档读取不全的现象;使用’rb’按照二进制位进行读取的,不会将读取的字节转换成字符,二进制文件用二进制读取用’rb,’rt‘模式下,python在读取文本时会自动把\r\n转换成\n,文本文件用二进制读取用‘rt’。当我们写文件时,操作系统往往不会立刻把数据写入磁盘,而是放到内存缓存起来,空闲的时候再慢慢写入。只有调用close()方法时,操作系统才保证把没有写入的数据全部写入磁盘。忘记调用close()的后果是数据可能只写了一部分到磁盘,剩下的丢失了。
python绘图
matplotlib
matplotlib 是python中最有名的绘图库,在编写较大的应用程序时使用matplotlib会更加有效。如果需要绘制某种类型的图表,在http://matplotlib.sourceforge.net/gallery.html 这个页面找到对应自己需要的,然后粘贴复制即可,基本上略微的修改就可以直接的拿来使用了。和matlab中的绘图十分的相似,如果熟悉matlab绘图的话,对于了解这块绘图会有十分大的帮助。有的时候不得不佩服那些粘贴复制的,带我兜兜转转,问题没解决掉,反而使得时间浪费了不少。看了Dipanjan Sarkar的博客,绘图就是门艺术,这里就简要的说明下seaborn绘图的命令。
显示中文标题
更改编码方式以及使用本地字体,可用参考如下代码。
# -*- coding: UTF-8 -*- |
seaborn 的使用
在工作的时候遇到的问题,由于需要进行不同参数下的误差对比,所以用到了这个,这里简略的说明几个用法
ax.set_title(‘your title’), 设置标题
f.savefig(‘yourPic.eps’, dpi=360) ,保存图片,其中dpi可以理解为设置分辨率的。
ax.invert_xaxis(), x轴内容进行转过来显示。
ax.tick_params(axis=’x’,labelsize=6),刻度调整.
sns.set(),样式控制sns.set(style=’white’,palette=’muted’,color_codes=True),style为图表的背景主题,有5种主题可以选择:darkgrid (默认), whitegrid,dark,white,ticks, palette为设置主体颜色,有6种可以选择:deep,muted,pastel,bright,dark,colorblind
用despine进行边框控制:white和ticks参数的样式,都可以删除上方和右方坐标轴上不需要的边框。despine(top=True, right=True, left=False, bottom=False, offset=None, trim=False),默认无参数的情况下,是删除上面及右边的边框。offset可设置边框的偏移距离,trim设置删除边框的范围.
下面给出seaborn.heatmap详细的参数说明,主要摘抄了 计科小白兔的博文
seaborn.heatmap(data, vmin=None, vmax=None, cmap=None, center=None, robust=False, |
1,data:矩阵数据集,可以使numpy的数组(array),如果是pandas的dataframe,则df的index/column信息会分别对应到heatmap的columns和rows.
2,vmax,vmin, 图例中最大值和最小值的显示值,没有该参数时默认不显示.
3,linewidths,热力图矩阵之间的间隔大小
4, cmap,热力图颜色
5, ax,绘制图的坐标轴,否则使用当前活动的坐标轴。
6, annot,annotate的缩写,annot默认为False,当annot为True时,在heatmap中每个方格写入数据。
7, annot_kws,当annot为True时,可设置各个参数,包括大小,颜色,加粗,斜体字等:sns.heatmap(x, annot=True, ax=ax2, annot_kws={‘size’:9,’weight’:’bold’, ‘color’:’blue’})
8, fmt,格式设置,决定annot注释的数字格式,小数点后几位等;
9, cbar : 是否画一个颜色条
10, cbar_kws : 颜色条的参数
pandas的数据结构介绍
要使用pandas,得熟悉提供的两个主要数据结构:Series和DataFrame。
Series
Series是一种类似于一维数组的对象,它由一组数据(各种NumPy数据类型)以及一组与之相关 的数据标签(即索引)组成,感觉和字典有一点相似。Series的字符串表现形式为:索引在左边,值在右边。由于我们没有为数据指定索引,于是会自动 创建一个0到N-1(N为数据的长度)的整数型索引。pandas的isnull和notnull函数可用于检测缺失数据。对于许多应用而言,Series最重要的一个功能是,它会根据运算的索引标签自动对齐数据。
DataFrame
DataFrame是一个表格型的数据结构,它含有一组有序的列,每列可以是不同的值类型(数值、字 符串、布尔值等)。DataFrame既有行索引也有列索引,它可以被看做由Series组成的字典(共用 同一个索引)。DataFrame中的数据是以一个或多个二维块存放的(而不是列表、字典或别的一维数据结构),建DataFrame的办法有很多,最常用的一种是直接传入一个由等长列表或NumPy数组组成的字典。DataFrame构造函数所能接受的各种数据如下所示。
- Numpy 中的集合函数
方法 | 说明 |
---|---|
unique(x) | 计算 x 中的唯一元素,并返回有序结果 |
intersect1d(x,y) | 计算 x 和 y 中的公共元素,并返回有序结果 |
union1d(x,y) | 计算 x 和 y 的并集,并返回有序结果 |
in1d(x,y) | 得到一个表示“x 的元素是否包含于 y”的布尔型数组 |
setdiff1d(x,y) | 集合的差,即元素在 x 中且不在 y 中 |
setxor1d(x,y) | 集合的对称差,即存在于一个数组中但不同时存在于两个数组中的元素 |
伪随机数生成,部分 numpy random 函数
函数 | 说明 |
---|---|
seed | 确定随机数生成器的种子 |
permutation | 返回一个序列的随机排列或返回一个随机排列的范围 |
shuffle | 对一个序列就地随机排列 |
rand | 产生均匀分布的样本值 |
randint | 从给定的上下限范围内随机选取整数 |
randn | 产生正态分布(平均值为 0, 标准差为 1) 的样本值,类似于 MATLAB 接口 |
binomial | 产生二项分布的样本值 |
normal | 产生正态(高斯)分布的样本值 |
beta | 产生 beta 分布的样本值 |
chisquare | 产生卡方分布的样本值 |
gamma | 产生 Gamma 分布的样本值 |
uniform | 产生在[0,1) 中均匀分布的样本值 |
这里重点的说一下如何使用 pandas
+ DataFrame
输出 xlsx
文件,这也是自己在工作中经常会遇到的一个问题,这里字典就会很有用处。这里先介绍下批量生成字符串的一种很简单的方法,比如自己在处理运动指令IP值时,对于机器人来说,有六个轴的,自己写 IP1,IP2,IP3 ...
, 久而久之就会很烦的。。。。下面这样就会使得问题变得很简单(类似的,对于字符串可用 %s
来替代)
indexNames = ['IP%d'%i for i in range(1,7) ] |
这样配合着字典,比如
for i in range(6): |
再利用
df = pd.DataFrame(dic) |
即可将结果输出到 *.xlsx
文件中去了, 这里忘了交代个事,就是需要引入相关的包
import pandas as pd |
参考
[1] 菜鸟教程