注:本笔记面向有一定基础的人
本笔记是本人快速复习python过程中记录的,不适合零基础的人学习python的主工具,可以作为辅工具,本笔记记录了入门阶段常用操作,如有错误的地方,希望读者不吝赐教。
# 1 打印变量类型
print(tpye(变量名))
# 2 打印变量/对象 内存id
print(id(变量))
# 3 list -- 列表
c=[10,2,1]
# 4 tuple -- 元组
c=(10,2,3)
# 5 set -- 集合
c={10,2,1}
# 6 dict -- 字典
c={
'1':1,
'2':2,
}
学习内容 :格式化符号,格式化方法,转义字符
格式符号 | 转换 |
---|---|
%s | 字符串 |
%d | 有符号十进制数 |
%f | 浮点数 |
%.3f #保留几位小数
print('我的名字是%s 今年%d岁了' % (name,age)) #输出内容和数据绑定用%链接
%06d #输出6位整数用0填充
#格式化字符串f'{表达式}'
print(f'我的名字是{变量名},今年{age}岁了')
#转义字符
\n \t
#print默认以\n作为end,但可以显示声明其他结束符号
print('hello',end='...')
#输入 input当作字符串处理,交给一个变量
input("提示信息")
函数 | 说明 |
---|---|
int(x[,base]) | 。。。 |
flot(x) | 。。。 |
str(x) | 。。。 |
⭐eval(str) | 计算字符串中有效的python表达式,返回一个对象 |
tuple(S) | 。。。 |
list(S) | 。。。 |
#把字符串里面的表达式转换为合适的类型
print(eval('[100,20]')) #[100,20]
#逻辑运算符
and or not
#python可以用类数学写法,下面写法是合法的语法
15<=a<=70
#三目运算符 化简简单的ifelse语句
c=a if a>b else b #如果条件成立 c=a 否则c=b
# for和while后面都可以跟else 表示循环正常结束后执行,brek为非正常结束
while t<10:
...
else:
...
#切片 [开始:结束:步长 ] 其中若为二维数组则还可以这么些[开始:结束:步长,开始:结束:步长] 左闭右开不包括结束符,但是包括开始符、
#其中-7表示倒数第7个
#下列函数用法变量名.方法名
#---------------------查找--------------------
#find(子串,开始位置,结束位置) 查找是否存在某字串 返回第一次找到该字串所在母串中的位子
mystr = 'hello world and itcast and itheima and Python'
print(mystr.find()) #12
#rfind()与find()相同,从右往左查找
#count()和find()的参数相同,返回出现次数
#index()与find()完全相同,find未找到返回-1 index未找到返回异常
#---------------------修改1--------------------
#replace(旧字串,新字串,替换次数) 把旧字串替换为新字符串
#split(字符串,次数) 返回是一个列表,用字符串分割split数组,其中次数代表的是分隔符出现的次数,次数为2分割后数据为3个
#join(多字符串组成的序列) !用法特殊!
'...'.join(['12','34']) #12...34
#---------------------修改2--------------------
#capitalize() 第一个大写
#title() 每个单词首字母大写
#lower() 大写转小写
#upper() 小写转大写
#lstrip() 删除左侧空白
#rstrip() 删除右侧空白
#strip() 删除两侧空白
#---------------------格式化--------------------
#ljust(长度,填充字符) 左对齐 第二个参数不些默认空格填充
#rjust 右对齐
#center 中间对齐
mystr='hello'
print(mystr.ljust(10,'.')) #hello.....
#---------------------判断--------------------
#startwith(字串,开始,结束) 判断是否为字串开头 返回布尔类型
#endwith(字串,开始,结束) 判断是否为字串结尾
#isdigit()是否全是数字
#isalnum()是否是由字母和数字的组合组成
#isspace()是否全是空格
#注字符串的拼接直接用+号就可以
#index 和字符串相关的函数一样
#count() 和字符串相关的函数一样
#len() 列表里面元素的个数
#判断某个数据是否存在
in / not in
'lily' in name_list #如果lily在name_list中返回true
'lily' not in name_list
#添加数据
#append(元素) 把元素添加到列表尾 如果是序列则把整个序列添加进列表
#extend() 同上,但参数可以是一个序列,并且把该序列所有元素依次添加进列表
#insert(位置下表,数据) 指定位置增加数据
#删除数据
#del(数组变量/下标) 删除列表 把整个列表删除 或者删除下标元素
#pop() 删除指定位置元素 默认删除最后一个数据 返回被删除的数据
#remove() 删除指定元素
#clear() 清空
#修改
#reverse() 反转列表
#sort(key=None,reverse=False ) 列表 reverse为False 升序
#列表复制
#copy() 注:python中列表只有一个存储,所有的名字都执行同一个空间,可以当作指针理解,因此修改列表需要复制一份然后再删除
元组中的数据不能修改 ,元组数据不能修改,但是元组里面有列表,列表中的数据可以修改
t1=(1,2,3)
print(t1[1]) # 2
print(t1.index(2)) #1
t1=(1,2,[1,2])
t1[2][0]=2
print(t1) #(1,2,[2,2])
#只有一个元素的元组要这么写
(1,)
#新增数据
dic['1']='2' #如果dic中没有‘1’这个key值则添加新的键值对,如果key存在则修改
#删除
#del()同列表
#clear()同列表用法相同
#查找
dic['1']
dic.get('1',2) #如果查找不到key为'1'则返回默认值2
#遍历字典
#counts.items()为字典的迭代器,获取到的是字典中的键值对元组
dic1={'name':1,'age':2,'gender':3}
for key,value in dic1.items():
print(f'{key}={value}')
#!!对字典进行拆包得到的是key!!
去重,和列表相比 集合里面没有重复的数据
#创建集合
s1={1,2,3}
s1=set() 创建空集合 #注:s1={}表示s1为空字典
#增加数据
#add() s1.add(10) 如果重复不进行任何操作
#updata() !注意增加的数据是列表
#删除数据
#remove 删除指定数据, !没有不报错!
#discard() 删除指定数据 !没有报错!
#pop() 随机删除数据并返回删除的数据
#查找数据
in / not in
运算符 | 描述 | 支持的容器类型 |
---|---|---|
+ | 合并 | 字符串、列表、元组 |
* | 复制 | 字符串、列表、元组 |
in | 元素是否存在 | 字符串、列表、元组、字典 |
not in | 元素是否不存在 | 字符串、列表、元组、字典 |
函数 | 描述 |
---|---|
len() | 容器元素个数 |
del del() | 删除 |
max() | 容器元素最大值 |
min() | 容器元素最小值 |
range(start,end,step) | 生成从start到end的数字,步长为step,供for循环使用 |
enumerate(可遍历对象,start=0) | 函数用于将一个可遍历的数据对象组合为一个索引序列,同时列出数据和数据下表,一般用在for循环当中。start为遍历对象下表起始值(计算机默认为0可以手动调节为1) 返回值为index,value |
更有风格的python代码书写,代码量更少
用一个表达式创建一个有规律的列表,或者控制一个有规律的列表
list1=[i for i in range(10)] #其中左面的i是回填的数据格式,右面的i是生成的i 还可以在继续对i添加if条件,满足条件才回填
print(list1)
# [0,1,2,3,4,5,6,7,8,9]
#创建偶数的列表
list1=[i for i in range(10) if i%2==0 ]
print(list1)
# [0,2,4,6,8]
#多for循环
list1=[(i,j) for i in range(1,2) for j in range(3)]
print(list1)
#[(1, 0), (1, 1), (1, 2), (2, 0), (2, 1), (2, 2)]
快速合并列表为字典或者提取字典中目标数据
dic={i:i**2 for i in range(1,5)}
print(dic)
#{1: 1, 2: 4, 3: 9, 4: 16}
list1=['张三','李四','王五']
list2=[18,20,13]
dic={list1[i]:list2[i] for i in range(len(list1)) }
print(dic)
#{'张三': 18, '李四': 20, '王五': 13}
#提取counts中的value满足一定条件的数据
counts={'map':123,'hp':1233,'dell':298,'acer':981}
count1={key:value for key,value in counts.items() if value>=200} #!注: counts.items()为字典的迭代器,获取到的是字典中的键值对元组
print(count1)
#{'hp': 1233, 'dell': 298, 'acer': 981}
list1=[1,1,2]
#返回list1中每个数据的二次方组成的集合
set1={i **2 for i in list1}
print(set1)
#{1,4}
#查看函数说明文档
def 函数名(参数):
"""说明文档"""
代码
......
help(函数名)
a=100
def test():
global a #声明a为全局变量的a
a=200
return
text()
print(a)
#200
*args **kwargs
其中的*可以看作一个运算,可以把
1,2,3,4
这种用逗号隔开的数据变为一个元组(1,2,3,4)
也可以把(1,2,3,4)
变为1,2,3,4
**则是把
age=20,name='asd'
用逗号隔开的key=value
复制变为一个字典,反过来也可以把字典变为key=value
赋值
def function(name,age,gender):
.....
# 传入参数的时候根据位置传入对应的形参
fdef function(name,age,gender):
.....
function('张三',gender='nv',age=18)
# 位置参数放在关键字参数之前,关键字参数顺序对结果无影响
def function(name,age,gender,test='1'):
.....
function('张三',18,'男') #此时默认test=1
function('张三',18,'男',2) #此时test=2
# 默认用*args作为不定长参数的传递
def user_info(*args):
#这里的args是一个元组
print(args)
#('Tom',)
user_info('Tom')
#('Tom',18)
user_info('Tom',18)
def user_info(**kwargs):
print(kwargs)
user_info(name='tom',age=18,id=110)
a,b=b,a #交换ab的值
在python中,值是靠引用传递过来的
a=1,b=a 此时b就是a的引用
函数值传递过程中实参的传送可以是引用
a=1
b=a #此时b是a的引用,指向同一块内存空间
#id()可以判断两个变量是否是同一个值的 引用可以理解为id是内存地址的标识
a=1
b=a
#此时id(a)与id(b)是一样的
a=2
#此时id(a)与id(b)是不一样的 并且a=2,b=1 a改变了因此开辟了一块新的空间存储新的值
aa=[10,20]
bb=aa
bb[0]=11
print(aa)
#[11,20]
#注意通过函数传送的值也是引用,函数体内如果要修改数组,记得copy一下
在修改数组
如果函数只有一个返回值,并且只有一句代码,可以使用lambda简化
lambda 参数列表: 表达式(返回值)
fn2=lambda :100 #fn2是一个函数
print(fn2) #打印的是内存地址
print(fn2()) #是函数返回值
pritn(fn1(1,2,3))fn1 =lambda a,b:a+b #有参数
fn1 =lambda a,b,c=100:a+b+c #默认参数
fn1 =lambda *args:agrs #可变参数 元组
pritn(fn1(1,2,3))
fn1 =lambda **args:agrs #可变参数 字典
pritn(fn1(name='c',age=2))
fn1= lambda a,b : a if a>b else b
print(fn1(1000,500)) #1000
#列表(里面是字典)根据字典某个确定key的value值进行排序
student=[{'name':'ad','age':20},{'name':'a','age':30},{'name':'ab','age':10}]
student.sort(key=lambda x:x['age']) #这里的x代指列表里面的字典 根据字典中的name的value值排序
print(student) #[{'name': 'ab', 'age': 10}, {'name': 'ad', 'age': 20}, {'name': 'a', 'age': 30}]
把函数作为参数传入,函数式编程的体现,
def function(a,b)
return abs(a)+abs(b)
def function(a,b)
return round(a)+round(b)
#上面两个函数可以写为一个
def function(a,b,f) #f是一个函数
return f(a)+f(b)
result=function(1,2,abs)
result=function(1.2,2.7,round)
函数 | 作用 |
---|---|
map(func,lst) | 将传入的函数变量func作用到lst变量的每个元素中,结果返回迭代器(python3)返回(需要进行过类型变换) |
reduce(func,lst) | func必须有两个参数。作用是func(func(func(func(func(func(a,b),c),d),e),f),g) |
filter(func,lst) | 过滤到不符合func条件的元素,返回一个filter对象,如果转换为列表用list() |
#----------------map(func,lstt)-----------------
list1=[1,2,3,4,5]
def func(x):
return x**2
result=map(func,list1)
print(result) #内存地址
print(list(result)) #列表
#----------------reduce(func,lstt)-----------------
#list1累加
def func(a,b):
return a+b
result=reduce(func,lst1)
print(result) #整形
#----------------filter(func,lstt)-----------------
#需要的是一个返回布尔型的函数
def func(a):
return x%2==0
result=filter(func,lst1)
print(result) #内存地址
print(list(result)) #列表
类名函数 满足大驼峰命名 变量满足小驼峰
print(类名.__mro__) #打印当前类所继承的父类及其层级关系
print(类名/实例名.__dict__) #打印类或者实例里所有的属性和方法组成的字典
# self指代调用该函数的对象,可以通过self访问该对象的数据 相当于this
class Washer():
def was(self):
print(self)
test = Washer()
print(test)
print(test.was)
class Washer():
def was(self):
print(self)
test1 = Washer()
test2=Washer()
#test1 与test2 不一样,python的对象是多例的
#类外面添加属性 这是和别的编程语言不同的
class Washer():
def was(self):
print(self)
test = Washer()
test.widteh=500
test.height=800
#类的外面获取属性 对象名.属性名
#类里面获取属性 self.属性名 只能获取对象拥有的属性
# __xx__()形式的函数叫做魔法函数,用作特殊作用
class Washer():
def __init__(self): #在创建对象的时候自动执行 无参
self.width=500
self.heigth=300
def was(self):
print(self)
test = Washer()
class Washer():
def __init__(self,width,height): #在创建对象的时候自动执行 无参
self.width=width
self.heigth=height
def was(self):
print(self)
test = Washer()
#打印对象实际上打印的是对象的内存地址,如果定义了__str__方法,那么就会打印从这个方法中return的数据
class Washer():
def __init__(self): #在创建对象的时候自动执行 无参
self.width=500
self.heigth=300
def was(self):
print(self)
#str魔法方法大多都是介绍该类的作用
def __str__(self):
return "这是一个洗衣机类"
result=Washer()
print(result) #这是一个洗衣机类
class Washer():
def __init__(self): #在创建对象的时候自动执行 无参
self.width=500
self.heigth=300
def was(self):
print(self)
#str魔法方法大多都是介绍该类的作用
def __del__(self):
print("对象已经删除")
result=Washer()
del result #对象已经删除 注意不用手动del,在程序执行完后会自动删除对象,执行del魔法方法
带有call魔法方法的类可以当作函数一样调用
class Check(object):
def __call__(self,*args,**kwargs):
pritn("我是call方法")
c=Check()
c() #向函数一样调用该类对象的call方法
#object是继承,默认继承顶级类就是object类
class 类名(object):
代码
print(类名.__mro__) #打印当前类所继承的父类及其层级关系
继承默认继承父类的所有属性和方法
多继承默认使用第一个类的同名属性和方法
#子类重写父类同名方法,默认使用子类的同名方法,那么如何利用父类的同名方法呢
class Master(object):
def __init__(self):
self.kongfu='123'
def make_cake(self):
print(f'利用{self.kongfu}')
class Prentice(Master):
def __init__(self):
self.kongfu='1'
def make_cake(self):
print(f'利用{self.kongfu}')
#在子类中把和父类重名的方法重新写一遍,Master代指父类
def father_master_make_cake(self):
Master.__init__()
Master.make_cake()
# 调用本类的直接父继承的方法 遵循mro类属性顺序,适合单继承使用
super().方法名
私有权限不会继承给子类
# 属性名以__开头的是私有属性,__开头的是私有方法
class Master(object):
def __init__(self):
self.kongfu='123'
self.__money=20000
def __info_print(self):
print(f'我的资产{self.__money}')
#获取和修改私有属性 只能在类内获取和修改私有属性
class Master(object):
def __init__(self):
self.kongfu='123'
self.__money=20000
def __info_print(self):
print(f'我的资产{self.__money}')
#获取和修改私有属性的值
def get_money(self):
return self.__money=money:
def set_money(self,money):
self.__money=money
子类重写父类的方法,传入不同的子类,执行不同的方法
class Dog():
def work(self):
print("开始工作")
class ArmyDog(Dog):
def work(self):
print("追击敌人")
class DrugDog(Dog):
def work(self):
print("追击毒品")
class ClassificationDog():
def work(self,dog):
dog.work()
cd=ClassificationDog()
ad=ArmyDog()
dd=DrugDog()
cd.work(ad) #追击敌人
cd.work(dd) #追击毒品
类拥有的属性,被该类所有的对象所共享,可以用实例对象访问,也可以用类来访问
class Dog(object):
tooth=10 #这就是类属性
类属性只能通过类修改,无法通过实例修改,如果实例修改类属性,则是创建和类属性同名的实例属性而已
class Dog(object):
tooth=10 #这就是类属性
wangcai=Dog()
Dog.tooth=12
print(wangcai.tooth) #12
需要用装饰器@classmethod
类方法用来获取类私有属性 类方法用类名或者实例对象名访问
class Dog():
__tooth=10
@classmethod
def get_tooth(cls): #cls指代的是类,self指代的是实例对象
return cls.__tooth
test=Dog()
print(test.__tooth) #报错
print(test.get_tooth) #10
用装饰器staticmethod来修饰,不需要传递对象不需要传递实例对象 即没有self或者cls
静态方法也可以通过实例对象和类对象访问
class Dog():
@staticmethod
def info_print():
print('这是一个狗类用于创建狗实例...')
test=Dog()
test.info_print()
Dog.info_print()
try:
可能发生异常的代码
except:
发生异常后执行的代码
#单个
try:
可能发生异常的代码
except 异常类型:
发生异常后执行的代码
#多个
try:
可能发生异常的代码
except (异常类型1,异常类型2):
发生异常后执行的代码
#捕获异常描述类型
try:
可能发生异常的代码
except (异常类型1,异常类型2) as result:
print(result)
#!!其中Exception代表所有异常!!
try:
可能发生异常的代码
except Exception as result:
print(result)
else:
没有异常后执行的代码
finally:
无论如何都会执行的代码
异常可以嵌套
import time
try:
f=open('test.txt')
try:
while True:
content=f.readline()
if(len(content)==0):
break
time.sleep(2)
print(content)
except:
print('意外终止了读取数据')
finally:
f.close()
print('关闭文件')
except:
print('无法打开该文件')
不符合程序逻辑要求 把其设置为异常来提醒用户
- 自定义异常类
- 抛出异常 raise关键字加异常类(如有初始化参数写在这里)
- 捕获异常
# 自定义异常
class ShotrInputError(Exception):
def __init__(self, length, minlength):
self.length = length
self.minlength = minlength
# 异常抛出信息
def __str__(self):
return f'您输入的长度为{self.length},不能少于{self.minlength}'
# 测试类
def test():
try:
con = input('请输入密码:\n')
if (len(con) < 10):
# raise抛出异常
raise ShotrInputError(len(con), 10)
except ShotrInputError as result:
print(result)
else:
print('密码已经输入完成')
# 测试开始
test()
如果import则会导入所有,包括测试,那么如何让测试只在模块内调用呢?
# 自定义异常
class ShotrInputError(Exception):
def __init__(self, length, minlength):
self.length = length
self.minlength = minlength
# 异常抛出信息
def __str__(self):
return f'您输入的长度为{self.length},不能少于{self.minlength}'
def test():
try:
con = input('请输入密码:\n')
if (len(con) < 10):
# raise抛出异常
raise ShotrInputError(len(con), 10)
except ShotrInputError as result:
print(result)
else:
print('密码已经输入完成')
# 其中如果在当前模块运行则__name__==__main__,如果不是在当前模块,比如被别人导入了本模块 ,则__name__等于模块名
if __name__ == '__main__':
test()
搜索模块顺序
如果一个模块中有all变量,,使用from xxx import *导入时,只能导入这个列表中的元素(即把模块功能写近all列表中,导入的时候只导入注册到all列表中的方法)
#这是一个模块
__all__=['test1']
def test1():
print('test1')
def test2():
print('test2')
#只有test1方法能被导入到其他文件中
文件夹,里面是一些有联系的模块。包里面有个init.py文件,用于控制导入包的内容
init.py 里面添加all=[],里面写上允许导入的模块名
在本部分中将介绍python的高级用法包括进程线程 装饰器等
创建子进程实际上把主进程的资源拷贝了一遍,他们俩之间互不干扰。因此不共享全局变量
# 1 导入模块 multiprocessing 创建进程对象 并启动
def func_a():
for i in range(5):
print('A进程在执行')
def func_b():
for i in range(5):
print('B进程在运行')
if __name__ == '__main__':
process1=multiprocessing.Process(target=func_a)
process2=multiprocessing.Process(target=func_b)
process1.start()
process2.start()
# 2 执行带有参数的任务
process1=multiprocessing.Process(target=func_a,args=(1,2,3)) #args传送参数元组方式,kwargs后面跟字典
process2=multiprocessing.Process(target=func_b)
process1.start()
process2.start()
# 1 获取进程编号
import os
getpid() #获取当前运行进程编号
getppid() #获取当前父进程编号
主进程等待所有子进程工作后才会结束
# 1 主进程默认等待所有子进程的执行
def func_a():
for i in range(10):
print('工作中...')
time.sleep(0.2)
if __name__ == '__main__':
process1=multiprocessing.Process(target=func_a)
process1.start()
time.sleep(1)
print('主进程工作完成')
# 2 主进程结束后,子进程自动结束 【1 设置子进程为守护主进程,主进程完成后,子进程会自动结束】【2 也可以手动销毁子进程】
process1.daemon=True
peocess1.start() #【方法一】
process1.terminate() #【方法二】
多任务可以利用多线程使用,进程会分配资源,线程只是执行,不会分配资源
比如:要给两人两天两个窗口 如果用多进程则每个窗口都有资源,如果用多线程就会节省资源
线程之间的执行是无序的,由cup调度决定
线程之间共享全局变量
# 1 创建多线程 【和多进程类似只不过把名字变了】
import threading
import time
def func_a():
for i in range(10):
print('工作中...')
time.sleep(0.2)
def func_b():
for i in range(10):
print('学习中...')
time.sleep(0.2)
if __name__ == '__main__':
thread1=threading.Thread(target=func_a,daemon=True)
thread2 = threading.Thread(target=func_b)
thread1.start()
thread2.start()
time.sleep(1)
print('主进程工作完成')
# 2 设置守护主线程
thread1.setDaemon(True)
# 3 线程对象信息
info=threading.current_thread()
print(info)
# 4 验证多线程之间共享全局变量
my_list=[]
def func_a():
for i in range(10):
my_list.append(i)
print('add:',i)
time.sleep(0.2)
print(my_list)
def func_b():
print(my_list)
if __name__ == '__main__':
#创建子线程
thread1=threading.Thread(target=func_a)
thread2=threading.Thread(target=func_b)
thread1.start()
thread1.join(timeout=10) #等待本线程执行完毕,可以设置超时时间
thread2.start()
# 1 互斥锁的使用
mutex=threading.Lock() #获取一个锁 【在主进程中】
mutex.acquire() #在子线程中上锁
mutex.release() #在子线程中解锁
函数名实际上存放的是函数的地址
# 1 例子1
def func01():
print("func01 is shwo")
print(func01)
func02=func01
func02() #【func01 is shwo】
# 2 例子2
def func01():
print("func01 is shwo")
def fun(func):
func()
fun(func01) #【func01 is shwo】
函数内部的局部变量,在函数运行完后,就被销毁了。但有时候,我们需要保存,函数执行过程中的局部变量。
定义:
- 在函数嵌套前提下,
- 内部函数使用了外部函数的变量,
- 并且外部函数返回了内部函数
我们把这个使用外部函数变量的内部函数称为闭包
# 1 闭包例子
def func_out(num1): #【创建函数闭包】
def func_inner(num2):
num=num1+num2
print('num:',num)
# func_inner就是闭包
return func_inner
f=func_out(10) #f是闭包实例,是一个闭包 【函数闭包实例化】
f(20)
f(30) #可以看到10使用了多次
# 2 闭包的使用
'''
张三:到北京了么?
李四:到北京了
张三:北京冬天冷么?
李四:冷!
'''
def func_out(name):
def func_inner(info):
print(f'{name}:{info}')
return func_inner
ZhangSan=func_out("张三")
LiSi=func_out("李四")
ZhangSan("到北京了么?")
LiSi("到北京了")
ZhangSan("北京冬天冷么?")
LiSi("冷!")
# 3 闭包可以修改外部变量 nonlocal
def func_out(num1):
def func_inner(num2):
nonlocal num1 #【声明外部函数变量】
num1=num2+10
print('num1:',num1)
print(num1)
func_inner(20)
print(num1)
return func_inner
f=func_out(10)
在不改变函数源代码的情况下,给函数增加新的功能
封闭开放原则:源代码不修改,但是可以根据实际扩展需求(框架设计)
装饰器的本质是闭包
# 1 例子1
def comment():
print("发表评论")
def check(fn): #【定义一个装饰器】
def inner(): #【增加新功能】
print("请登录")
fn() #【不要忘记原有的功能】【此时inner就变为了一个既有新功能又有原功能的函数(还是原函数)】
return inner
comment=check(comment) #用装饰器装饰一下函数 【即增加新的功能】
comment()
# 2 例子2 使用语法糖写法
def check(fn): #【定义一个装饰器】
def inner():
print("请登录")
fn()
return inner
@check #comment=check(comment)
def comment():
print("发表评论")
comment()
#【通过本例子读者应受到启发,可以把一些固定不变的语法放到装饰器中,然后我们只需要写不同的内容函数,然后用该装饰器装饰一下即可。】
# 3 装饰器的使用,统计函数的执行时间
import time
def get_time(func):
def inner():
start=time.time()
func()
print("程序执行时间为:",time.time()-start)
return inner
@get_time
def func():
for i in range(100000):
print(i)
func() #装饰后,执行该函数的时候执行完会打印函数的执行时间
# 1 装饰有参数的函数(一般参数)
def logging(func):
def inner(a,b): #inner内部参数和被装饰函数的参数一样多
func(a,b) #被装饰的函数
return inner
@logging
def sum_sum(a,b):
print(a+b)
sum_sum(1,2)
#【显然这么做泛用性大大降低了,不同的原始函数可能有不同的参数,仅仅一个装饰器无法胜任】
# 2 装饰带有返回值的函数
def logging(func):
def inner(a,b):
result=func(a,b) #装饰器获取原函数的返回值
return result #装饰器把原函数的返回值返回
return inner
@logging
def sum_sum(a,b):
return a+b
print(sum_sum(1,2))
# 3 通用装饰器(任何参数和返回值)
def logging(func):
def inner(*args,**kwargs):
#新功能增加
result=func(*args,**kwargs)
return result
return inner
@logging
def sum_sum(*args,**kwargs):
print(args,kwargs)
sum_sum(1,2,2,3,5,6,age='20',name='asdf')
谁距离原函数近,先装饰谁
# 1 多个装饰器例子
def checkuser(func):
def inner(*args,**kwargs):
print("登录验证")
result=func(*args,**kwargs)
return result
return inner
def checkinfo(func):
def inner(*args,**kwargs):
print("审核通过...")
result=func(*args,**kwargs)
return result
return inner
@checkuser
@checkinfo
def comment():
print("发表评论")
comment()
使用装饰器装饰函数的时候可以传入指定参数,注意此时的参数是装饰器的参数而不是函数的参数
# 1 例子1
def logging(flag): #在装饰器外面添加一个接受参数的函数,然后把真正的装饰函数返回
def decorator(func):
def inner(num1,num2):
if flag=='+':
print("正在计算假发")
elif flag=='-':
print("正在计算剑法")
result=func(num1,num2)
return result
return inner
return decorator
@logging('+')
def add(a,b):
result=a+b
return result
print(add(1,4))
# 1 例子
class Check(object):
def __init__(self,fn):
self.__fn=fn
def __call__(self,*args,**kwargs):
print("登录")
self.__fn()
@Check #【comment=Check(comment)->实际上创建了一个类的实例,comment()就调用该实例的call方法】
def comment():
print('发表评论')
comment()
负责把类中的方法当作属性去使用
获取私有属性的方法可以当作属性去使用(装饰器方式,类属性方式)
- 用法,一般把私有属性设置为property属性,这样形式上私有属性可以作为普通属性使用,但实际是受到保护的私有属性。
# 1 快速访问私有属性
class Person(object):
def __init__(self):
self.__age=0
@property #【property属性,该属性的名字和下面方法的名字一样】
def age(self):
return self.__age
p=Person()
print(p.age)
# 2 修改property属性
class Person(object):
def __init__(self):
self.__age=0
@property #【property属性】
def age(self):
return self.__age
@age.setter
def age(self,new_age):
self.__age=new_age
p=Person()
p.age=100
print(p.age)
#【实际上property属性的名字就是被装饰的函数的名字,设置的时候也要用该函数的名字去设置属性】
#【这就产生了一个有趣的现象。我们定义一个私有属性age,却在设置property属性的时候把函数命定义为agee,那么我们的实例化对象要通过 对象名.agee来获得私有属性age。是不是很奇怪!】
#【继续,我们想要修改私有属性age设置的时候,要用property属性的名字.setter设置 因此我们增加装饰器@agee.setter,但我们却把被装饰的修改函数的名字写成了age。那么神奇的事情发生了!,我们需要用agee来获取私有属性age,但是修改的时候却要用age来修改!!】
#【因此我们规定,property属性一定要设置成和要获取的属性相同的名字,修改该属性的时候也要用相同的名字】
# 1 类属性方法设置属性为property属性
class Person(object):
def __init__(self):
self.__age=0
def get_age(self):
return self.__age
def set_age(self,new_age):
self.__age=new_age
age=property(get_age,set_age) #【注意这里参数的顺序是先get在set,并且传入的是函数名】
p=Person()
p.age=100
print(p.age)
- with语句
简单安全的使用
自动关闭文件,异常的时候关闭文件
with在调用方法的时候会先调用上文方法, with语句结束后 或者发生异常 再调用下文方法
# 1 with语句操作文件
with open('test.txt',"r") as f:
file_data=f.read()
print(file_data)
- 上下文管理器
管理某些操作所需要的前提操作,和必要的后续操作
- 定义上下文管理器
类中由enter和exit方法的对象,就是上下文管理器
with修饰可以在使用方法的时候执行上文方法,并且自动执行下文方法
open方法是一个上下文管理器,因此with修饰后才可以做到自动关闭文件
# 1 上下文管理器 【模拟实现open()方法,上下文管理器】
class File(object):
def __init__(self,file_name,file_model):
self.file_name=file_name
self.file_model=file_model
def __enter__(self):
print("进入上文方法")
self.file=open(self.file_name,self.file_model)
return self.file
def __exit__(self, exc_type, exc_val, exc_tb):
print("进入下文方法")
self.file.close()
with File("test.txt","r") as f:
print(f.read())
根据设计者指定的规则,循环生成数据,当条件不在成立时,不再生成数据
数据不是一次性全部生成出来的,而是使用一个再生成一个,可以节约大量 【内存】
- 生成器的使用场景介绍,
比如我们使用列表推导式生成了100个数据,t1时间我们需要10个,此时由100个数据,t2时间我们需要20个此时有20个数据,t3时间我们需要100个,此时有100个数据。如果我们可以根据使用的情况自动生成相应的数据,t1有10个,t2的时候再生成10个,t3的时候再生成80个,这样是不是就节省空间了?
【注意: 获取的值只能顺序获取 无法做到随机取值】
# 1 生成器推导式创建推导式
my_list=(i for i in range(100))
next(my_list) #next(生成器名字)获取一个数据【按照顺序一个一个获取】
# 2 yield关键字 在函数内部生成数据
def mygenerater(n):
for i in range(n):
print('开始生成...')
yield i #【暂停(状态保存)并且把i返回】【下次启动时在暂停位置重新开始】
print('完成一次')
#【for循环在生成完后会自动抛出异常,处理异常】
for i in mygenerater(10)
print(i) #【for循环 这种方法在使用完后不会产生异常】
# 3 实例,生成斐波那契数列
def fb(num):
a=0
b=1
#记录生成了几个数字
index=0
while index<num :
result=a
a,b=b,a+b #a是当前位置上的数,b是下个位置的数
index +=1
yield result
for i in fb(10):
print(i)
copy函数是浅拷贝,只对可变类型的第一层对象进行拷贝
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-hywPMTY4-1681201977314)(python基础和第三方库.assets/image-20230411152124866.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-xavALWQl-1681201977315)(python基础和第三方库.assets/image-20230411152401580.png)]
# 1 浅拷贝例子
import copy
a=[1,2,3]
b=[11,22,33]
c=[a,b]
d=c
e=copy.copy(c)
print(id(d))
print(id(c))
print(id(e))
#【可以看到 dc一样e和他们不一样】
print(id(a))
print(id(d[0]))
print(id(c[0]))
print(id(e[0]))
#【可以看到全都一样,也就是说内层数据都是指向同一块空间的】
# 2 浅拷贝不可变数据类型 直接引用,不会开辟新的空间
拷贝,所有都拷贝
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-1VcXyCwW-1681201977316)(python基础和第三方库.assets/image-20230411153415683.png)]
# 1 深拷贝例子
import copy
a=[1,2,3]
b=[11,22,33]
c=[a,b]
e=copy.deepcopy(c)
print(id(c[0]))
print(id(e[0]))
#【上面的结果是不同的】
# 1 深拷贝 不可变类型 同浅拷贝一样,不开辟任何空间,是一个引用
基于文本规则的代码
0\d{2}-\d{8}
这是一个正则表达式,匹配的是一个以0开头加两个数字加一个-再加8个数字的字符串 例如012-12345678
# 1 re模块
import re
result = re.match(正则表达式,要匹配的字符串) #【匹配到是一个结果,没匹配到是None】
result.group() #获取匹配好的字符串
代码 | 功能 |
---|---|
. | 匹配任意一个字符 |
【】 | 匹配【】中的字符 |
\d | 数字 |
\D | 匹配非数字 |
\s | 匹配空格 tab键 |
\S | 匹配非空白 |
\w | 匹配非特殊字符 a-z A-z 0-9 _ 汉字 |
\W | 匹配特殊字符 *±/!,。 |
import re
result = re.match("itcast.", 'itcast1')
result = re.match("itcast[1234abcd]", 'itcasty') #【注意[]中没有逗号】
result = re.match("itcast[0-9]", 'itcasty') #【匹配0-9】
info = result.group()
print(info)
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Gv95dIq0-1681201977317)(python基础和第三方库.assets/image-20230411155659760.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-IXxZRkP9-1681201977318)(python基础和第三方库.assets/image-20230411155957464.png)]
result = re.match("^\d*\w*", '1324adsfdsa') #【以任意多个数字为开头,之后跟着任意多个常规符号】
result = re.match("^\d*\w*\d$", '1324adsfdsa') #【必须以数字为结尾,\d$】
result = re.match("^d.*[^4]$", '1324adsfdsa') #【必须以数字为结尾,\d$】
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-DnHmABHd-1681201977318)(python基础和第三方库.assets/image-20230411160824715.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-PdHSZymm-1681201977319)(python基础和第三方库.assets/image-20230411160923962.png)]
# 1 【匹配多个确定的序列】
import re
fruit=["apple",'banana',"orange","pear"]
for i in fruit:
result = re.match("apple|pear|orange", i)
if result:
info = result.group()
print(info)
# 2 【|多与()一起用在()中选择】
result = re.match("[a-zA-Z0-9_]{4,20}@(163|qq|126).com", "[email protected]")
if result:
info = result.group()
print(info)
# 3
result = re.match("(qq):([1-9]\d{4,11})", "qq:12345")
if result:
info = result.group(1) #【group中的参数代表的是第几个分组 ,分组从1开始】
info = result.group(2)
print(info)
# 4
result = re.match("<([a-zA-Z1-6]{3,4})>(.*)(\\1>)", "hh") #【注意\\1】
if result:
info = result.group()
print(info)
# 5 【多分组】
result = re.match("<([a-zA-Z1-6]{4})><([a-zA-Z1-6]{2})>.*\\2>\\1>", "hh
")
if result:
info = result.group()
print(info)
# 6 【分组别名】
result = re.match("<(?P[a-zA-Z1-6]{4})><(?P[a-zA-Z1-6]{2})>.*(?P=h1)>(?P=html)>"
, "hh
")
if result:
info = result.group()
print(info)
数值计算库,里面有一些自己的数据结构
import numpy as np
t1=np.array(list)
t1.dtyp #求属性,t1的类型
t1.shape #属性,形状 是一个元组
t1.T
#创建一个数组
t1=np.array(list1)
t2=np.array(range(n))
t3=np.arange(10) #和range类似,自动生成0到9之间的np.array类型的数组
#创建全为0/1的数组
t1=np.zeros((a,b)) #创建a行b列的一个全为0的数组
t1=np.ones((a,b)) #创建a行b列的一个全为1的数组
#创建一个主对角线全为1的方阵
t1=np.eye(3) #3X3的
#数据类型
t4=np.array(range(n),dtype='int64') #dtype指定数据的类型
t4.astype("float32") #astype()是调整数据类型
#数据精度操作
t5=np.array([random.random() for i in range(10)]) #生成一些小数
t6=np.round(t5,2) #t6为t5中每个数字取两位小数后的结果
# 1 二维数组,以2行为例子
t4=np.array([list1,list2])
# 2 三维数组
(a,b,c) #a表示数据块数,b,c表示每块里面的二维行列数
# 3 修改形状 注意reshape不会改变原数组
t1.reshape((3,4)) #改成3行四列的二维数组 【不修改元数据】
# 4 展开
t1.flatten() #【不修改元数据】
t1=np.array(list)
# 1 数组加一个数
t2=t1+5 #t1中每个数据都+5 同理-*/也一样
t2=t1/0 #? 结果是一个同为数组,由nan和inf组成,nan表示不是一个数,inf表示无穷 其中0/0=nan 非0/0=inf
# 2 两个同维度数组计算
t2=t1+t1 #两个数组形状相同 对应位置相加—*/同理
#3 n*m-1*m /n*m-n*1 【结果是n*m中每行的列都减去1*m中对应列的元素/后者同理。同理-*/也一样】
# 4 数组的布尔运算
t1<10 #得到的是同纬度数据,每个数据小于10为true大于10为false
# 5 数组的转置
t1.T #这是一个属性,【不改变原来的数据】
# 1 取数组中一个数或者某行某列
t1=np.array(list)
t2=t1[1][1] #取一行一列的数据,注意行列从0开始排序 【结果是np.int类型或者np.float类型】
t2=t1[1,1] #【和第三行代码结果相同】
t2=t1[1] #t1的一行 【是一维数组】
# 2 取多行或者多列 【返回的是二维数组】
t1[2:5,0:2] #(连续)2到5行,0到2列数据
t1[[1,2,5],0:2] #(离散)1,2,5行的0到2列数据
# 3 取不连续的一些点的数据 【返回的是一维数组】
t1[[1,3,4],[1,5,4]] #取(1,2),(3,5),(4,4)列这三个数据
# 4 bool索引
t1[t1>10] #找到数据小于10的数 【返回一个一维数组】
# 5 数组的拼接
np.vstack((t1,t2)) #竖直拼接,同列数
np.hstack((t1,t2)) #水平拼接,同行数
# 6 条件取值
temp[条件] #取条件成立情况下的值
# 1 首先通过索引切片找到要修改的数据,然后修改即可
# 2 条件修改
t1[t1<10]=1 #修改数组中比10小的数字为1
# 3 三目运算符修改
np.where(t1<=10,0,10) #t1中小于等于10的为0 其他的为10 【会修改原数据】
# 4 clip裁剪操作
t1.clip(10,18) #小于10的替换成10,大于18的替换成18
# 5 nan赋值
t1[2,3]=np.nan #t1的(2,3)数据修改为nan
# 6 交换数组的某行某列
t[[1,2]:]=t[[2,1],:] #t交换一行一列 【会修改原数据】
# 1 numpy的引用
a=b #是一个引用,互相影响但不会创建新的对象
# 2 copy
a=b.copy() #复制一份
# 3 view
a=b[:] #试图操作,会创建新的对象a,a与b的数据变化是一致的
# 1 最值函数
np.argmax(t,axix=0) #求0轴方向上的最大值的index,即求每一列的最大值索引【返回的是一个一维数组】
np.argmin(t,axis=1)
np.max()
t.max() #求最大值
t.min()
# 2 生成随机数
np.random.rand(2,3) #随机生成2行3列的数组 【取值为0-1,符合均匀分布】【float】
np.random.randn(2,3) #随机生成2行3列的数组 【取值为0-1,符合正太分布,均值为0,方差为1】【float】
np.random.randint(low,high,(a,b)) #随机生成a行b列的数组 【取值为low-high,符合均匀分布】【int】
np.random.nuiform(low,high,(a,b)) #随机生成a行b列的数组 【取值为low-high,符合均匀分布】【float】
np.random.normal(loc,scale,(a,b)) #随机生成a行b列的数组 【取值为low-high,符合正太分布,均值为loc,方差为scale】【float】
np.random.seed(10) #确定随机数种子之后每次生成的随机数一模一样,再程序测试阶段使用
# 3 求两个数组中不相同元素的个数
np.count_nonzero() #求数组里面不为零的数的个数
np.count_nonzero(t1!=t2) #求t1中对应位置元素和t2相同的个数 【同维度,t1如果不等于t1就为1】
#下列统计函数无论使用np. 还是数组名.都可以
# 4 求和函数
np.sum(t1) #求所有元素的和
t.sum()
np.sum(t3,axis=0) #所有列相加的结果【返回一个一维数组】
np.mean() #平均值
np.median() #中位数
np.ptp() #极值
np.std() #标准差
- nan与inf都是float
- nan和任何元素运算都为nan
# 1 nan是不相等的
# 2 判断nan的个数
np.count_nonzero(t!=t)
np.isnan(t2) #如果是nan则为true
后续对数组的各种操作都建立在轴上
shape(a,b,c) a是0轴 b是1轴 c是2轴 不同维度的数据轴的排列是不一样的
二维数组 行方向是0轴,列方向是1轴
三维数组 块方向是0轴,行方向是1轴,列方向是2轴
基于numpy实现的更具类
可以处理数值之外的而数据,包括字符串,时间序列等
#属性Series
dtype #对象属性,返回对象里面数据的类型
index #索引
values #values 【返回的是一个数组】
ndim #数据维度
# 1 数据类型
Series #一维带标签的数组 值得就是索引
DataFrame #二维 Series容器
# 2 指定索引 【关于索引,如果传入的是字典,a,a和索引能对应起来的则取值,如果索引里面有a里面没有取NAN,如果a里面有索引里面没有则忽略该值】
pd.Series([1,2,3,4],index='abcd')
# 3 通过字典创建Series
dic={
'a':1,
'b':2,
'c':3,
}
a=pd.Series(dic)
# 4 修改数据类型
a.astype(float) #同numpy操作类似
# 5 取值
a['a'] #索引来取
a[0] #位置取值
a[[1,2,3,4]]
a[:3]
a[['a','b','c']] #如果没有这个索引取到的是nan
t[t>4]
# 6 to_list
a.to_list #把Series转换为列表
# 1 读取csv
df=pd.read_csv('filepath') #【结果是一个FrameDate类型数据】
有一个index索引行索引,和一个columns列索引,代表的是列属性 默认从0开始增加
# 1 创建DateFrame
pd.DataFrame(np.arrange(12).reshape(3,4),index=list('abc'),columns=list('ABCD')) #【接收的参数是一个二维数组】
# 2 根据字典/列表创建DateFrame
a={
'name':['1','2'],
'age':[18,20],
'tel':[100,120]
}
b=[{'name':'1','age':18,'tel':100},{'name':'2','age':20,'tel':120}]
pd.DateFrame(a) #【注意字典的格式,values是列表】
pd.DateFrame(b) #【注意列表的格式,元素是字典】
# 3 数据显示方法
df.head(5) #头部5行
df.tail(5) #尾部5行
df.info() #相关信息,行列数,非空值个数,列类型,内存占用
df.describe() #统计结果:计数,均值,标准差等等等 【只有数值列才可以计算】
# 4 排序方法
dp.sort_values(by='列名',ascending=False) #根据某一列排序 #ascending默认为true递增排序
# 5 取值
df['列名'] #取具体某一列 【返回值是Series】
df[0]['列名'] #取某个数据
df[:20] #取前20行
df.iloc[:20,:20] #和其他数据类型的取行列效果一样【注意要用iloc方法来取】 【通过位置获取】
df.loc[['a','b'],['A','B']] #和iloc效果类似 【通过行列索引名字取值】
df.loc['a':'f',['w','z']] #连续取行,【注意af都被选中】
# 6 布尔索引
df[df['a']>800] #取df的a列中大于800的数据
df[(df['a']>800)&(df['a']<1000)] #多个索引条件需要用&链接
# 7 DateFrame里面的字符串
da['A'].str.len() #求da的A列里面的每个元素的len【注意要用str.len()才能让len作用到每一行】
# 8 数据插入
data.insert(0,'ones',1,axis=1)数据插入,插入到第零列,起名字为ones,用1填充
# 1 判断nan
pd.iana(df)
pd.notna(df)
df.isna() #返回的结果都是布尔类型
# 2 删除nan
df.dropna(axis=0) #找到nan按照行删除
df.dropna(axis=0,how='all') #找到nan按照行删除 【只有某行全部为nan才删除】
df.dropna(axis=0,how='all',inplace=True) #【原地修改该变量】
# 3 填充nan
df.fillna(100) #填充100给nan
df.fillna(df.mean()) #自动根据某列的平均值来帮助我们填充该列nan
# !!注意,DateFrame利用统计方法默认是作用与每一列
# 1 把某列变成一个列表,其中每个元素只出现依次
df['Director'].unique() #【输出是一个列表】
# 2 列表里面还是列表 转换为一个单列表
a=np.array([1,2,3],[4,5,6])
b=a.flatten() #【1,2,3,4,5,6】
a=[[1,2,3],[4,5]] #列表里面的列表长度不相同
b=[i for j in a for i in j] #【1,2,3,4,5】
# 3 统计方法 可以获取某一列后进行统计计算
df['列明'].mean()
df['列明'].min()
df['列明'].median()
df['列明'].argmax()
# 1 案例
temp_list=df['Category'].str.split(',').tolist() #先把Category里面的每个电影的类型字符串分割,然后合并成一个[[],[],[]]
category_list=(list(set([i for j in temp_list for i in j]))) #把一个[[],[],[]]=>[] 并且通过set去重
zeros_list=pd.DataFrame(np.zeros((df.shape[0],len(temp_list))),columns=temp_list) #创建一个全为0的数组,行为数据的行,列为所有类型的列
#给每个电影出现分类的位置复制为1
for i in range(df.shape[0]):
zeros_list.loc[i,temp_list[i]]=1
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-8I5wvM9u-1681201977319)(python基础和第三方库.assets/image-20230408145034374.png)]
# 1 水平拼接 (左右拼接)
t1.join(t2) #以t1的行为基准,没有的数据用nan
# 2 条件合并 (左右合并)
t1.merge(t2,on='a') #笛卡尔积操作,但是只有t1,t2中a列数据相同的行进行笛卡尔积
# 1 分组 【按照某一列的不同值进行】【分组后的结果实际上就是index和values】
group=df.groupby(by='列名')
for i,j in group:
print(i,j) #i是该列的值,j是该列为i值的DataFrame对象
# 2 聚合方法
group.count() #统计按照某列分组后,不同的分组中其他列包含多少条数据
group.mean() #统计按照某列分组后,不同的分组中其他列数据的平均值
# 3 对多列进行分类,并且只求分类后数据某一列的count值
group=df['Brand'].groupby(by=[df['country'],df['province']])
print(group)
group=df[['Brand']].groupby(by=[df['country'],df['province']]) #两个[[]]结果是DateFrame
# 1 以某列数据作为索引
df.set_index('列名',drop=False) #【drop=False该列不会被删除,不会改变df原来的索引】
df.set_index(['列名1','列名2']) #【多索引】
#注意Series可以直接用ad['索引名字']来取值,但是DateFrame需要用ad.loc['索引名字']来取值
# 1 生成一段时间范围
pd.data_range(start=None,end=None,Periods=None,freq='D') #periods代表生成几个时间
pd.date_range(start='20171230',end='20180131',freq='10D') #生成一段时间,按照10天间隔十个昵称
# 2 把字符串转化为格式化时间类型
pd.to_datetime('字符串',format='') #format告诉程序用什么样的程序进行格式化操作
# 3 时间重采样
t.resample('M').mean() #t是一个时间类型,按照月份进行重采样 并且求平均值
# 4 时间格式化
t.strftime("%Y-%m-%d") #t是一个时间格式的变量,strftime进行时间格式化
数据画图工具
散点图,直方图,柱状图
可以去官网查看不同的图形代码样例,改一下就可以
#修改matplotlib字体
matplotlib.rc()
plot()绘制折线图
from matplotlib import pyplot as plt #导入包
x=range(2,26,2) #折线图x轴
y=[15,13,14,17,20,25,26,26,24,22,18,15] #折线图y轴
plt.plot(x,y)
plt.show()
#其中xy轴的刻度是根据给定的数据自动生成的
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-rzwle70y-1681201977319)(python基础和第三方库.assets/image-20230405105404192.png)]
import matplotlib.pyplot as plt
#画图前修改图片大小dpi等属性信息
plt.figure(figsize=(20,8),dpi=80)
#数据配置
x=range(2,26,2)
y=[15,13,14,17,20,25,26,26,24,22,18,15]
#绘图
plt.plot(x,y)
# !!设置x轴相关
#设置x轴的刻度
plt.xticks(x) #用x列表里面的值设置x轴的刻度
plt.yticks(range(min(y)-2,max(y)+2))
#设置x轴的刻度为字符串
plt.xticks(x,_str) #x和_str一一对应,不显示x里面的值,而是显示对应的在_str里面的值 注意x与_str中的元素个数要相同
#旋转90度 ratationx轴标记旋转90度
plt.xticks(x,_str,rotation=90)
#设置X轴字体为中文
my_front = font_manager.FontProperties(fname="字体路径")
plt.xticks(_x,_str,fontproperties=my_front)
#保存图片,可以保存为svg或者png
plt.savefig("./t1.svg")
plt.show()
plt.xlabel("时间")
plt.ylabel("温度")
plt.title("时间温度情况")
plt.grid(alpha=0.4) #根据x轴和y轴的刻度绘制网格 alpha为透明度
#为曲线添加名字
plt.plot(x1,y1,label='a')
plt.plot(x2,y2,label='b')
#添加标签,即曲线名字 如果要使用中文 关键字为prop
plt.legend(prop=my_font)
#显示在左上角
plt.legend(prop=my_font,loc="upper left")
#橙色和虚线,点表示 #color也可以用16进制颜色代码,记得前面加#
plt.plot(x,y,label='self',color='orange',linestyle=':')
plt.plot(x,y,label='self',color='orange',linestyle='--')
#设置网格形状
plt.grid(alpha=0.4,linesytle='--')
#plt.scatter()绘制即可,其他的描述语言和折线图一样
plt.scatter(x,y) #xy是列表
#plt.bar()
plt.bar(x,y,width=0.3) #xy是列表 width修改条状图的宽度
#横着绘制
plt.barh(x,y,height) #注意这里的xy不变,x还是自变量,y还是因变量 但是在后面plt.xtick的时候因为x轴和y轴反转了,因此需要修改
#绘制多个条形图
#和其他图形多次绘制相同,不过需要注意的是不同图形的x轴要偏移一点
import matplotlib.pyplot as plt
x=['test1','test2','test3','test4','test5']
y1=[203,231,45,73,123]
y2=[123,55,62,724,212]
y3=[123,356,21,41,612]
width=0.2
x1=[i for i in range(5)]
x2=[i+width for i in range(5)]
x3=[i+ width*2 for i in range(5)]
plt.bar(x1,y1,width=width,label='x1')
plt.bar(x2,y2,width=width,label='x2')
plt.bar(x3,y3,width=width,label='x3')
plt.legend()
plt.xticks(x2,x)
plt.xlabel('X')
plt.ylabel('Y',rotation=90)
plt.title('test')
plt.show()
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-akY6jikQ-1681201977320)(python基础和第三方库.assets/image-20230406102609010.png)]
和条形图的区别就是 x轴连续
import matplotlib.pyplot as plt
import random
#随机300个数,求从0到100步长为10之间的数的个数,比如0-10之间的个数,10-20之间的个数 其中区间是[a,b)
y1=[random.randint(0,100) for i in range(300)
x1=[i for i in range(0,101,10)]
plt.hist(y1,x1) #其中y1是原始数据,x1是我们设置的值,该直方图用于统计y1中落在x1中相邻两个数之间的个数
plt.xticks(x1)
plt.grid()
plt.show()
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-jbAUJ2jy-1681201977326)(python基础和第三方库.assets/image-20230406110009373.png)]
matplotlib其他图形网站
http://matplotlib.org/gallery/index.html
关于前端交互式绘图可以参考如下网站,通过numpy和pandas把数据处理好传送过去即可
Apache ECharts
plotly 画图界的GitHub
https://plot.ly/python/
#随机数x a<=x<=b
random.ranint(a,b)
abs() #绝对值函数
round() #四舍五入函数
conda install [package name]
conda activate [环境名]
conda deactivate #退出虚拟环境
读文件数据处理相关
data = pd.read_csv('ex1data1.txt',names=['population','profit'])
第一个参数是文件名,并且在当前文件目录下,第二个参数names给文件的列起名字 返回值是dataframe类型
data.head()
data.tail() 打印出data的后几行
data.describe() #数据信息统计
data.info() #数据结构信息
reg=np.insert(reg,0,values=0,axis=0)在第零行插入一个值values 行插入用axis=0 reg为被插入的数据
data.iloc[:,0:-1]数据切片 默认有逗号隔开,从0列开始一直到倒数第一列之前的(不包括倒数第一列)
np.array(x) 把dataframele类型转换为数组类型(矩阵)
X.shape 看看x是什么样的矩阵
Y.reshape(n,m)把y重塑成N x M型的矩阵
X@Y 矩阵乘法
X*Y 矩阵点乘,表示矩阵对应元素相乘,型不变
np.zeros((2,1))初始化一个2行一列的矩阵,默认值为0
cost.append(cos) cost数组后面添加一个元素cos
x=np.linspace(0,25,100) 生成一个以为列表 最小值为0最大值为25 一共100个数
acc=np.mean(y_pre==Y) y_pre==y为1否则为零,之后求平均值
映射函数,把线性映射到非线性 其中power是最大的次数
def feature_mapping(x1,x2,power):
data ={} #定义一个字典用来存储映射后的数据
for i in np.arange(power+1):
for j in np.arange(i+1):
data['F{}{}'.format(i-j,j)]=np.power(x1,i-j)*np.power(x2,j)
return pd.DataFrame(data) #把字典变成dataframe类型的数据
tpye(data) data的类型
data['X'] 获取X值的字典
绘图相关
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-IGasSrPB-1681201977326)(C:\Users\顾子茵\AppData\Roaming\Typora\typora-user-images\image-20230228144924039.png)]
fig,ax=plt.subplots(a,b) 绘图实例ax其中有a X b个图,无参默认一个图
ax.plot(a,b,label='') 绘制曲线图,横坐标数为a,纵坐标数为b其中a b都是一维数组 label 表示绘制的该条曲线的标签
ax.scatter(a,b,label='') 散点图,其中 a,b为列表
plt.scatter(X[:,0],X[:,1],c=Y.flatten(),cmap='jet') #根据Y值的不同绘制颜色不同的点
ax.legend() 如label无法显示出来就加上一句
ax.set(xlable='',ylabel='',title='')x轴的名字 y轴的名字 图的名字
ax.scatter(data[data['accepted']==0]['exam1'],data[data['accepted']==0]['exam2'],c='r',marker='x',label='y=0')
#data[data[iaccepted]==0]['exam1']取出data中所有accepted==0的exam1列数据为x轴数据,同理为y轴数据,marker='x' 用x表示该点
等高线画法
登高线图画法
x=np.linspace(-1.2,1.2,200)##均匀分布的数组,-1.2到1.2之间
xx,yy=np.meshgrid(x,x) 生成与x行 与y列对应 的二维矩阵
z=feature_mapping(xx.ravel(),yy.ravel(),6).values xx.ravel()把二维矩阵变成向量 xx.flatten()表示把行向量或者列向量变成一维数组的形式。
zz=z@theta_final
zz=zz.reshape(xx.shape)
plt.contour(xx,yy,zz,0) 话等高线,其中0表示只画出zz为0的等高线
决策边界
def plot_boundary(model):
x_min,x_max=-0.5,4.5
y_min,y_max=1.3,5
xx,yy=np.meshgrid(np.linspace(x_min,x_max,500),np.linspace(y_min,y_max,500))
z=model.predict(np.c_[xx.flatten(),yy.flatten()])
zz=z.reshape(xx.shape)
plt.contour(xx,yy,zz)
svm包
svc1=SVC(C=1,kernel='linear/rbf', gamma=gamma) #获取一个svc模型实例,传入相应的c值选择对应的核函数gamma是和函数里的方差
svc1.fit(X,Y.flatten()) #x是矩阵,返回一个一维数组,比如吧n行1列的列向量变成一个一维数组
svc1.predict(X) #输入矩阵后输出对应的预测结果
svc1.score(X,Y.flatten) #获取该模型的精确度
ray.get 获取到的值为(array([]),2,3,‘stirng’)时如何获取array或者string
以上述例子
result=ray.get(work1_id)[1] 结果是2
result=ray.get(work1_id)[3] 结果是string
# 1 返回第n个字母 从a到z
a=string.ascii_uppercase[5] #【返回第五个字母大写的E】