Python
For 循环
#常与range 配套使用:
range(start,end,step) #函数左闭右开
从start到end-1
step代表步长,可以省略,默认为1
#基本语法
for i in range(start,end,step):
print(i)
for X in 可迭代对象:
可执行操作
嵌套循环时,先执行内循环,再执行外循环
for i in range(1,3):
for j in range(1,3):
print(i,j)
continue跳出本次循环
break终止整个循环
for i in range(1,3):
print(i)
if i==5:
break
if i==6:
continue
for _ in range(n):
#代表省略循环变量,i,用_d可以循环n次
Try / except:
#捕捉可能出现的异常
try :代码块
except: 出现异常后执行的代码块
else :未出现异常的代码块
finally: 无论如何都会执行的代码块
try-except结构代表代码如果去掉try结构会报错,和 if-else不同
except结构可以写多个,以捕捉不同的异常
可以用 as 来命名未出现的Exception
try:
代码
except 异常的名字:
执行结果
Print:
prit函数可以显示一些文本或结果,字符串,数值,以及其他的复杂的数据类型。
print可以输入多个参数
print可以设置 end 参数
Input:
实现计算机和用户的交互
a=input("请输入:")#“请输入”这是提示语
缩进结构
Python使用冒号和缩进来表示代码块之间的分层。
缩进可以用TAB来执行,也可以用四个空格。
语句断行
#同一行执行两段代码,则需要用分号 ;
a=2;b=3
print(a);print(b)
则结果是
2
3
#语句过长时,用\来进行换行,让本行语句不要结束,继续在下一行执行。
a=\
2
b=\
3
print(a)
print(b)
则结果是
2
3
数字类型
int 表示整数
float 浮点数
type(a):查看a的类型
字符串
用单引号‘’或者双引号“”
可以用方括号和索引值来取字符串,索引从0开始,不是从1开始
a='今天天气很热'
print(a[0])#则结果为今
print(a[0:3])#左闭右开,结果为今天天
print(a[:3])#为今天天
print(a[0:])#为今天天气很热
#如果用负数,则表示从后往前数第几位
print(a[-1])#为热
print(a[-2])#为很
print(a[1:-1])#为从第一位取到倒数第二位,左闭右开
#字符串拼接
a='小明'
b='小强'
a+b就是小明小强
#字符串重复输出
a*2就是小明小明
#IN and NOT IN
in :判断字符串是否在其中
not in:判断字符串是否在其中
'11' in '11111'#结果为True
'22' not in '11111'#结果为False
#格式化:
将变量的值填充到字符串中
用%s占位符表示字符串变量,用%d表示整数变量,%f表示浮点型
format格式(推荐)
name='小明'
age=14
'我叫%s,今年%d岁' % (name,age)
'我叫{name},今年{age}岁' .format(name=name,age=age)
#三引号:适用于打一个段落,自动填充换行,无需手动添加
a='''
我叫小明
今年12岁
'''
print(a)
#结果就是
我叫小明
今年12岁
#自动换行
#replace函数
"旧字符串".replace ("旧字符串","新字符串")
#len函数
len("字符串")
#upper:变大写
'abc'.upper(),变为ABC
#lower:变小写
'ABC'.lower(),变为abc
#strip:去掉字符串的前后的空格
" abcdefg ".strip(),变为abcdefg,但是字符串中的空格不会去掉
int/float/str格式的转换
int("123"),变为123
float(123),变为123.0
str(123),变为"123"
运算符
#除法:
/
#返回整数部分:
//
#返回余数部分:
%
#幂次方:
**
3**2 为 9
#绝对值:abs(x)
abs(-3),结果为3
#is 判断内存地址是否相等
#is not 判断不相等
a=100
b=100
a is b ,为 False
a is not b ,为True
#布尔运算符
and :且
or:或
not:取反
#优先级
数值>比较>布尔,
改变运算顺序,用()
变量
命名规则:
字母,数字,下划线,但是不能以数字开头,
标识符不能是Python的关键字或者保留字,但是可以包含关键字
不包含空格
区分大小写
列表
定义:一种有序且可以更改的数据集合
以 [] 来表示,以","分隔
元素可以是不同类型,不需要同一类型
可以嵌套
s_list=['01','02',3,'04',12.2,['03','04']]
nums=[1,2,3,2]
#列表尾部增加元素
list.append(value)#单个元素
list.extend(list)#多个元素
s_list.entend(['010','020'])
#列表中增加元素
list.insert(index,value)#index是开始插入的索引值,value是要插入的值
#修改更新
list[index]=value#和数组差不多,直接修改值
#删除
对index进行删除:del(index)
对index进行删除,并且取出删除值:list.pop(index)
针对value进行删除(移除出现过的第一个值):list.remove(value)
nums=[1,2,3,2]
del nums[2]#直接删除
x= nums.pop(1),则X=2,此时nums=[1,3,2]
nums.remove(2),nums=[1,3,2]
#查找
查找索引所对应的值:list[index]
查询,值第一次出现的索引:list.index(value)
#长度
len(list)
#判断子元素
in / not in,结果为 True/False
print(2 in nums)
#拼接和重复
拼接:+, 重复:*
nums + [1,2,3]
nums*3
#取最大值/最小值
max(list)
min(list)
如果存在字符串,则通过ASCII码来比较,可以通过 ord()内置函数来获取ASCII码,仅仅只是用于字符串之间的比较
无法比较 str 和 int/float
#排序
list.sort() 和 sorted:
list.sort()会改变 list 本身,而 sorted,不做用于自身,而是有一个返回值,返回一个新的列表
X=sorted(nums)
list.sotr()和 sorted函数,默认为正序排列,
list.sort(reverse=True),为倒序排列
#反转
list.reverse()
反转时根据 list的index索引来进行反转,不是根据元素的大小。单纯的前后反转
#统计次数
list.count(value)
统计value出现的次数
#将序列转换为列表
list()
str_example='abc'
list(str_example),就变为['a','b','c']
#拷贝/copy
list.copy()
nums_cpoy=nums.copy()
nums_copy与nums元素相同,但是两者的地址不同,是两个独立的 list
而nums_copy=nums,此时nums_copy与nums,是同一个 list,此时,改变任何一个,另一个也会随之改变
#遍历
通过index 进行遍历
nums=[1,2,3,4]
for i in range(0,len(nums)):
nums[i]++
print(nums)
结果为:[2,3,4,5]
通过value进行遍历
nums=[1,2,3,4]
for value in nums:
print(value)
结果为:
1
2
3
4
index 和 value一起遍历:用 enumerate
nums=[1,2,3,4]
for index,value in enumerate(nums):
print(index,value)
则结果为:
index value
0 1
1 2
2 3
3 4
enumerate 其实是一种内置的数据类型
索引
可以通过索引来过去列表中的元素
默认从0开始,可以是负数#若果是负数,则是倒数第几个
可以通过索引来对列表进行切片,切片可以超出边界
print(s_list[0])
print(s_list[-1])#倒数第一为
print(s_list[2:5])#进行切片,去第2为到第4位
print(s_list[0:100])#只会取到实际存在的地方
元组
定义:一种有序且无法更改的集合,支持不同的数据类型
以()的形式表示,用','分隔
以 tuple 表示
元组的索引法和列表完全一样
point=(1,1)
points=((1,2),(1,3),(1,4))
#元组的不可修改是针对顶层的,不是底层
point=(1,[2],4)
此时可以对 list [2]进行修改:
point[1].append(3)
此时point=(1,[2,3],4)
#单项元组后面需要加一个逗号
point=(2,)
此时point为一个单项元组
#
元组可以通过 zip()函数进行创建:
zip:将几个可迭代对象一起打包的函数
zip后返回的对象可以通过 list、 tuple、 dict等关键字转化为自己想要的类型
point =tuple(zip([1,2,3],[4,5,6,7,8]))
此时point=((1,4),(2,5),(3,6))
呈现一一对应的关系,多出来的不会被考虑
point =tuple(zip([1,2,3],[4,5,6,][7,8,9]))
此时point=((1,4,7),(2,5,8),(3,6,9))
#元组可以使用 + *运算
进行拼接和重复运算
#判断子元素是否在元组中:in/not in
#
最大值 max() ,最小值 min(),长度 len()
#将可变序列转化为元组:
tuple()
nums=tuple(nums)
#统计次数:
tuple.count(value)
#查找value第一次出现的索引index:
tuple.index(value)
#遍历循环:
index 角度
value 角度
enumerate角度
字典
定义:字典是一种由 key : value形式储存的数据集合,用{}来创建,用','分隔,是一种有序的集合
由key找到value,key不能重复
student_score={'小明':99,'小强':88,'小华':77}
#索引通过dict[key]来进行
dict[key]
student_score['小明']
#修改/新增键值对:
dict[key]=x
student_score['小明']=55
dict.update(dict)
student_score.update({'小白':22,'小黑':66})
#由索引查找值:
直接查找:dict[index]
student_score['小明']
dict.get(key,option:return value)
student_score.get('小张',10)
如果找到了'小张',则会返回'小张'所对应的值,如果没有找到,则会返回option,即 10
不会修改 dict
dict.setdefault(key,return value)
student_score.get('小张',10)
如果找到了'小张',则会返回'小张'所对应的值,如果没有找到,则会
把'小张':10,这个键值对 append到 dict的最后,实现对 dict的修改
#删除元素:
del dict[key]
dict.pop(key)
del 没有返回值,pop()由返回值,返回的是key对应的value
#取长度:
len()
#最大值,最小值:
max(),min()
取最大的key:max(dict)
取最大的value所对应的key:max(dict,key=dict.get),返回的是key,不是value
#判断key是否在 dict中:
in / not in
key in dict,结果为 True/False
#拷贝:
dict.copy()
#清空:
dict.clear()
#获取所有的键值对:
dict.items()
#获取所有的键:
dict.keys()
#获取所有的值:
dict.values()
#循环遍历:
key 遍历:
for key in dict.keys():
print(key)
print(dict[key])
假设什么也不写,默认对key进行遍历:
for x in dict:
print(x)
则x 就是 dict 的key
value 遍历:
for value in dict.values():
print(value)
一起遍历 key,value:
for key,value in dict.items():
print(key,value)
如果用 enumerate 遍历:
for key,value in enumerate(dict):
print(key,value)
结果为
0 key0
1 key1
2 key2
3 key3
结果为索引+key,而不是键值对
#转化为字典:
dict()
dict(zip([dict_keys],[dict_values])),出来的结果就是key 与value一一对应的 dict
集合
定义:集合是无序的,用{}创建,用逗号分隔
集合中没有重复的值
集合中的元素只能是不可变的类型
用 set表示
login_set={'2021','2022'}
login_set={(1,2)}
#并集:两个集合都要
|
set.union
#交集:两个集合的共同部分
&
set.intersection
#差集:将一个集合去掉一部分
-
set.difference
#交叉补集:交集的补集
^
set.symmetric_difference
#添加:不一定会加到末尾,是无序的;如果添加重复的元素,是不会添加的
添加单个元素:set.add(x)
添加序列元素:set.update(x)
#删除:
删除指定的元素,不存在会报错: set.remove(x)
删除指定的元素,不存在不会报错: set.discard(x)
删除随机的元素: set.pop(x)
#查找和修改:
因为无索引,所以无法通过索引查找和修改
#清除集合:
set.clear
#计算元素的个数:
len(set)
#最大值,最小值:
max(),min()
#判断是否在其中:
in / not in
#转化为集合:
set()
#可以用for循环遍历,但是不能用index进行遍历,并且非有序遍历,每一次的遍历结果不一样
for num in nums:
print(num)
函数
定义:以 def .关键字开头来定义,后面接括号
可以在函数中加入 return 来定义返回值,如果没有 return 则默认返回 None
定义函数时,括号内需要定义传入的参数(可选),有参和无参函数
整个函数的代码语句都需要缩进
函数名应当表达出该函数的实际意义,命名规则:
以字母、下划线、数字组成
用下划线法或者驼峰法链接每个单词
不能以数字开头
注意不要跟关键字重名
尽量为函数在第一行提供说明文档
def test(x):
return x**2
print(test(3))
#为什么要有函数:
将功能相同的代码单独提取出来,独立实现一个功能,供需要的的代码调用
为了方便多次调用已有的功能:如 len(),max(),min()
模块化代码,将一个大的问题拆分成不同的子问题
尽量每个函数都解决子问题,最后拼接起来解决整个问题
#函数的参数:
形参:形式上的参数,只在函数的内部被调用,所以只在函数的内部有效
实参:实际的参数,无论是常量,变量,必须有明确的值
即使调用的时候形参和实参同名,在函数内部也是调用形参
def computer_sum(x,y):
print(x)
print(y)
return x+y
一、传参的方式:
1.按位置顺序传参:
computer_sum(1,2):
1给了 x
2给了 y
2.关键字传参(可以不按顺序):
computer_sum(y=2,x=1):
y=2
x=1
3.默认参数:
(1)如果参数的值没有被传入,那么按照默认值来取:
def computer_sum(x,y=1):
print(x)
print(y)
return x+y
computer_sums(2)#此时只传了x,x=2,y=1,结果为3
computer_sums(2,3)#此时x,y都被传入了参数,x=2,y=3,结果为5
(2)在定义函数时,默认参数后面不可以跟非默认参数:
def cmputer_sums(x,y=1,z):
return x+y+z
#此时会报错
二、可变长参数:
用'*'表示
用'**'表示键值对参数
def call_xiaoming(*args):
print("小明是")
for i in args:
print(i)
call_xiaoming('a','b')
'''
结果就是
a
b
'''
def student_score(**kwargs):
print(kwargs)
student_score(小明=100,小白=98,小强=99)
#小明会自动变成字符串:'小明'
#结果为:'小明':100,'小白':98,'小强':99
#函数的嵌套:
函数的内部可以调用其他的函数:
其他的函数可以在内部定义,也可以在外部定义
内部定义的函数只能在内部使用,相当于局部变量
外部定义的函数,相当于全局变量
#匿名函数:
形式:lambda
形参:函数体
def square(x):
return x*x
print((lambda x : x**2)(2))#这两个是等价的
print((lambda x,y: y/x**2)(y=80,x=1.8))
目的:方便定义简单的只需要用一次或几次后就不再需要的函数,如果逻辑复杂,不建议使用匿名函数
匿名函数可以使代码更加的精简
匿名函数本质上也是一种函数,所以在传参等性质方面和普通的函数一样
#递归函数:
递归函数:函数中被调用自身的现象
递归要有一定的终止条件,不然会找不到递归出口,形成死循环
#阶乘函数:
def factorial(n):
if n==1:
return n
else:
return n*factorial(n-1)
#斐波那契额数列:
def fibo(n):
if n==1:
return 1
if n==2:
return 1
return fibo(n-1)+fibo(n-2)
类型注解
类型注解(Type Hinting) 是 Python 中的一种语法特性,用于在代码中显式地说明变量、函数参数和返回值的类型。虽然 Python 是动态类型语言,不要求在运行时指定变量的类型,但类型注解可以提高代码的可读性、可维护性,并且能够通过静态类型检查工具(如 MyPy)在开发阶段捕获潜在的类型错误。
1. 类型注解的基本用法
变量注解
你可以为变量指定类型注解:
x: int = 10
y: str = "Hello"
z: float = 3.14
在这个例子中:
x
被注解为int
类型。y
被注解为str
类型。z
被注解为float
类型。
函数参数和返回值注解
你可以为函数的参数和返回值指定类型注解:
def add(a: int, b: int) -> int:
return a + b
在这个例子中:
a
和b
参数被注解为int
类型。- 函数返回值也被注解为
int
类型。
2. 常见的类型注解
基本类型
常见的基本类型包括:
int
:整数float
:浮点数str
:字符串bool
:布尔值
组合类型
使用 typing
模块可以定义更复杂的类型。
-
Optional[T]
: 表示类型T
或None
,相当于Union[T, None]
。from typing import Optional def greet(name: Optional[str] = None) -> str: if name: return f"Hello, {name}!" return "Hello, world!"
-
Union[T1, T2, ...]
: 表示可以是T1
、T2
等多种类型中的任意一种。from typing import Union def to_string(value: Union[int, float, bool]) -> str: return str(value)
-
List[T]
: 表示一个列表,列表的元素类型为T
。from typing import List def sum_list(numbers: List[int]) -> int: return sum(numbers)
-
Tuple[T1, T2, ...]
: 表示一个元组,元组的各元素类型依次为T1
,T2
, ...from typing import Tuple def divide_and_remainder(x: int, y: int) -> Tuple[int, int]: return divmod(x, y)
-
Dict[K, V]
: 表示一个字典,键类型为K
,值类型为V
。from typing import Dict def count_occurrences(items: List[str]) -> Dict[str, int]: return {item: items.count(item) for item in items}
3. 高级用法
-
Any
: 表示任意类型。当你不确定或不关心类型时,可以使用Any
。from typing import Any def process(data: Any) -> None: print(data)
-
Callable
: 表示一个可调用对象(如函数),并可以指定它的参数和返回值类型。from typing import Callable def apply_func(func: Callable[[int, int], int], x: int, y: int) -> int: return func(x, y)
-
TypeVar
: 用于定义泛型类型,可以在函数、类中定义通用的类型参数。from typing import TypeVar, List T = TypeVar('T') def first_item(items: List[T]) -> T: return items[0]
-
NewType
: 用于创建类型的别名,主要用于语义化区分不同用途的同类型数据。from typing import NewType UserID = NewType('UserID', int) def get_user_name(user_id: UserID) -> str: ...
4. 类型注解的优势
- 提高可读性: 通过显式类型注解,其他开发者可以快速理解代码的意图和数据结构。
- 早期错误检测: 使用静态类型检查工具(如 MyPy),可以在代码运行之前捕获类型错误。
- 增强 IDE 支持: 类型注解帮助 IDE 提供更好的自动补全、类型检查和代码导航功能。
5. 类型注解的限制
- 运行时不会强制执行: 类型注解只是静态的,它不会在运行时强制检查变量的类型。
- 灵活性与复杂性的权衡: 在某些情况下,类型注解可能会增加代码的复杂性,特别是在使用高级类型时。
6. Python 3.10 引入的 |
语法
在 Python 3.10 及更高版本中,引入了 |
符号作为 Union
的简化写法:
def process(data: int | str) -> str:
return str(data)
这与 Union[int, str]
具有相同的效果。
7. 总结
类型注解是 Python 中一个强大的工具,能够提高代码的清晰度、可维护性,并帮助开发者在开发阶段捕获潜在的错误。虽然类型注解在运行时不强制执行,但结合静态分析工具,它们可以大大提高代码的质量。如果你对类型注解有更多问题或需要进一步的解释,请随时告诉我!
全局变量和局部变量
全局变量:在函数的内外都可以使用
局部变量:只能在函数的内部使用
如果要给函数内的全局变量赋值,必须使用 global 语句。
global 可以使局部变量在外部使用
def square(x):
y=x*x
return y
print(y)#此时报错,y无法在外部使用
def square(x):
global y
y=x*x
return y
print(y)#此时不会报错,global 使y可以在外部使用
return的使用
return代表函数执行后会有返回的数据,如国没有 return或者 return 后没有值,那么会返回 None
return可以返回多个值,类型为元组:
def squre(x):
a=x
b=x**2
return a,b
#结果为(a,b),以元组的的形式返回
return 被执行后,整个函数也结束
return 在函数内部可以多次出现,但最终只有一个被执行
模块
Python 模块(Module),是一个 Python 文件,以 .py 结尾,包含了 Python 对象定义和Python语句。
#模块的引入:
import module1[, module2[,... moduleN]]
'''当解释器遇到 import 语句,如果模块在当前的搜索路径就会被导入。
搜索路径是一个解释器会先进行搜索的所有目录的列表。如想要导入模块 support.py,需要把命令放在脚本的顶端'''
from modname import name1[, name2[, ... nameN]]
from 语句让你从模块中导入一个指定的部分到当前命名空间中
from modname import *
把一个模块的所有内容全都导入到当前的命名空间
#dir()函数
dir() 函数一个排好序的字符串列表,内容是一个模块里定义过的名字。
返回的列表容纳了在一个模块里定义的所有模块,变量和函数。
#globals() 和 locals() 函数
根据调用地方的不同,globals() 和 locals() 函数可被用来返回全局和局部命名空间里的名字。
如果在函数内部调用 locals(),返回的是所有能在该函数里访问的命名。
如果在函数内部调用 globals(),返回的是所有在该函数里能访问的全局名字。
两个函数的返回类型都是字典。所以名字们能用 keys() 函数摘取。
#Python中的包
包是一个分层次的文件目录结构,它定义了一个由模块及子包,和子包下的子包等组成的 Python 的应用环境。
简单来说,包就是文件夹,但该文件夹下必须存在 __init__.py 文件, 该文件的内容可以为空。__init__.py 用于标识当前文件夹是一个包。
Python OS文件/目录方法
super() 是用来解决多重继承问题的,直接用类名调用父类方法在使用单继承的时候没问题,但是如果使用多继承,会涉及到查找顺序(MRO)、重复调用(钻石继承)等种种问题。
Python3.x 和 Python2.x 的一个区别是: Python 3 可以使用直接使用 super().xxx 代替 super(Class, self).xxx :
#Python3.x 实例:
class A:
def add(self, x):
y = x+1
print(y)
class B(A):
def add(self, x):
super().add(x)
b = B()
b.add(2) # 3
#Python2.x 实例:
class A(object): # Python2.x 记得继承 object
def add(self, x):
y = x+1
print(y)
class B(A):
def add(self, x):
super(B, self).add(x)
b = B()
b.add(2) # 3
类和对象
Python是一门面向对象的语言,一切皆对象:函数,变量,类都是对象
对象:具体存在的一个东西
类:具体存在的一类东西,是对一群具有相同特征或行为的事物的一个统称,是抽象的,类似于模板,负责创建对象
类用于创建对象,对象被类创建
类的定义:由class定义,class.x代表类的某一个属性,可以给class.x赋值,定义class的某一个属性
#定义一个Student类:
class Student():
pass
#定义一个student_a对象:
student_a=Student()
#定义对象的属性:
student_a.age=18
student_a.number=1
#类中的_init_初始化方法:
通过_init_方法,将有必须要有的属性传进去
调用_init_方法,需要有关键字 self,表示创建的实例本身
如果有_init_方法,就必须要传递所需要的参数,其中 self不用传,否则报错
class Student():#定义类
def _init_(self,name,age,number):
self.name=name
self.age=age
self.number=number
student_b=Student('小明',18,2) #创建对象
student_c=Student()#此时报错
情况一:子类需要自动调用父类的方法:子类不重写__init__()方法,实例化子类后,会自动调用父类的__init__()的方法。
情况二:子类不需要自动调用父类的方法:子类重写__init__()方法,实例化子类后,将不会自动调用父类的__init__()的方法。
情况三:子类重写__init__()方法又需要调用父类的方法:使用super关键词
class Son(Father):
def __init__(self, name):
super(Son, self).__init__(name)
#第二种写法:父类名称.__init__(self,参数1,参数2,...)
#访问和修改对象的属性:
class.x=something
#类中的方法:
类中的方法,其实就是函数,有三种方式
1.实例化方法:第一个参数一定是实例自身的 self,即使改变参数名,第一个参数还是会表示 self的意思:
只能实例化调用
修改的是对象的属性
class Student():#定义类
def _init_(self,name,age,number):
self.name=name
self.age=age
self.number=number
def self_print_info(self):
print("名字为:"+self.name)
print("数量为:{number}".format(number=self.number))
student_d=Student('小红',2)
student_d.self_print_info()
'''
结果为:
名字为:小红
数量为:2
'''
2.静态方法:关键字 @staticmethod,不限制强制传入的参数,无法使用类内部的属性和方法:
可以直接通过类名调用也可以通过实例化调用
无法再方法的内部调用实例属性
class Student():#定义类
def _init_(self,name,age,number):
self.name=name
self.age=age
self.number=number
@staticmethod
def self_print_info(self):
print("这是一个静态的方法")
Student.self_print_info()
'''
结果为:
这是一个静态的方法
'''
3.类方法:关键字 @classmethod,定义时需要传入关键字 cls,该参数代表类自身:
可以直接调用也可以通过实例化调用
类方法修改的属性是类属性,不是对象的属性
class Student():#定义类
grade = 1
def _init_(self,name,age,number):
self.name=name
self.age=age
self.number=number
@staticmethod
def self_print_info(self):
print("这是一个静态的方法")
@classmethod
def calss_upgrade_print_info(cls):
cls.grade=cls.grade+1
#类的继承:
为了进一步缩小抽象的类,可以继承父类
形式为:class_son(class_father)
子类拥有父类的属性和方法
如果对于父类的方法需要重写,只需要在子类中重新重写方法
子类可以继承多个父类,形式如class_son(father1,father2)
class Animal():
def action(self):
print("该动物正在行动")
class Cat(Animal):
pass
cat = Cat()
cat.action()#此时调用的是父类的action,结果为:该动物正在行动
class Cat(Animal):
def action(self):
print("小猫正在行动")
cat.action#此时调用的是子类重写的action,结果为:小猫正在行动
#多继承:
class A():
def test_A(self):
print('a')
class B():
def test_B(self):
print('b')
class C(A,B):
pass
c= C()
c.test_A()
c.test_B()
多继承也可以重写
class C(A,B):
def test_A(self):
print('c')
元组解包
元组解包(Tuple Unpacking) 是 Python 中的一种语法特性,用于同时将一个元组(或任何可迭代对象)中的多个值赋值给多个变量。这个功能让代码更加简洁和易读,特别是在处理函数返回多个值的情况下。
1. 元组解包的基本语法
a, b, c = (1, 2, 3)
- 这里
(1, 2, 3)
是一个元组,包含三个元素。 - 通过元组解包,
a
被赋值为1
,b
被赋值为2
,c
被赋值为3
。
2. 不使用括号的元组解包
在 Python 中,括号是可选的,因此你可以直接写成:
a, b, c = 1, 2, 3
这在语法上与前面的例子是等效的。
3. 解包用于函数返回值
元组解包在处理函数返回多个值时特别有用:
def get_position():
return (10, 20)
x, y = get_position()
get_position()
返回一个元组(10, 20)
。x
被赋值为10
,y
被赋值为20
。
4. 解包用于交换变量
元组解包的一个经典用法是交换两个变量的值,而不需要借助临时变量:
a, b = 1, 2
a, b = b, a
这段代码将 a
和 b
的值交换,即 a
最终等于 2
,b
最终等于 1
。
5. 解包与可迭代对象
解包不仅限于元组,任何可迭代对象(如列表、字符串等)都可以使用解包:
a, b, c = [4, 5, 6] # 列表
x, y, z = "abc" # 字符串
6. 解包与剩余值(使用 *
)
Python 允许你使用 *
运算符来捕获解包时多余的值:
a, *b = 1, 2, 3, 4
a
被赋值为1
。b
被赋值为[2, 3, 4]
,它是一个列表,包含了剩余的所有值。
另一个例子:
*a, b = 1, 2, 3, 4
a
被赋值为[1, 2, 3]
。b
被赋值为4
。
7. 嵌套解包
Python 还支持嵌套解包,即在解包时直接解包嵌套的元组:
a, (b, c) = 1, (2, 3)
a
被赋值为1
。b
被赋值为2
。c
被赋值为3
。
8. 解包失败
如果元组(或可迭代对象)的长度与左侧变量的数量不匹配,Python 会引发 ValueError
:
a, b = (1, 2, 3) # 这将引发 ValueError: too many values to unpack (expected 2)
9. 总结
元组解包是 Python 中非常强大且灵活的特性,可以大大简化变量赋值、函数返回值处理和数据结构解构的代码。它不仅限于元组,还可以应用于任何可迭代对象,包括列表、字符串等。
如果你有更多问题或需要进一步的解释,请随时告诉我!
方法链
方法链(Method Chaining) 是一种编程技术,允许你在同一行代码中连续调用多个方法。每个方法调用返回一个对象,通常是原始对象本身或与原始对象相关的新对象,使得你可以继续调用下一个方法。这种风格可以使代码更加简洁和易读。
1. 方法链的基本原理
在方法链中,每个方法都返回一个对象(通常是 self
),从而允许在返回的对象上继续调用其他方法。以下是一个简单的例子:
class MyClass:
def method1(self):
print("Method 1")
return self
def method2(self):
print("Method 2")
return self
def method3(self):
print("Method 3")
return self
# 使用方法链调用
obj = MyClass()
obj.method1().method2().method3()
结果:
Method 1
Method 2
Method 3
2. 方法链的优点
-
代码简洁:方法链可以将多个方法调用写在一行代码中,减少冗长的代码。
obj.method1().method2().method3()
相比于:
obj.method1() obj.method2() obj.method3()
-
增强可读性:特别是在需要连续执行多个操作时,方法链可以使代码的逻辑更加直观。
3. 实际应用场景
a. 构造器模式(Builder Pattern)
方法链经常用于构造器模式中,特别是在需要创建复杂对象时:
class CarBuilder:
def __init__(self):
self.car = Car()
def set_color(self, color):
self.car.color = color
return self
def set_engine(self, engine):
self.car.engine = engine
return self
def build(self):
return self.car
car = CarBuilder().set_color("Red").set_engine("V8").build()
b. 数据操作库
像 Pandas 和 SQLAlchemy 这样的库广泛使用方法链来操作数据:
import pandas as pd
df = pd.DataFrame({"A": [1, 2, 3], "B": [4, 5, 6]})
result = df.drop(columns=["B"]).rename(columns={"A": "Column_A"}).head()
c. Web 框架
在一些 Web 框架(如 Flask)中,方法链用于路由配置和中间件的组合:
from flask import Flask
app = Flask(__name__)
@app.route("/").methods(["GET"]).secure().add_logging()
def index():
return "Hello, World!"
4. 注意事项
-
返回
self
:要实现方法链,关键是每个方法需要返回self
(或者返回与self
相关的对象)。如果方法不返回对象或返回None
,方法链将中断。 -
错误处理:在复杂的方法链中,确保适当地处理错误和异常,以防止某个方法调用失败导致整个链的中断。
5. 总结
方法链是一种优雅的编程技术,它允许在一个语句中连续调用多个方法,从而使代码更加简洁和易读。通过返回 self
或相关对象,你可以在一个对象上多次调用方法而不需要多次引用对象。这种技术在构建器模式、数据操作库、Web 框架等多种场景中广泛应用。
如果你有更多问题或需要更详细的解释,请随时告诉我!
Python的标准库
标准库:无需下载额外的库,可以 import后直接调用
1.math库:
import math
math.sqrt(num):计算平方根
math.ceil(num):向上取整
math.floor(num):向下取整
math.factorial(num):计算阶乘
函数 返回值 ( 描述 )
abs(x) 返回数字的绝对值,如abs(-10) 返回 10
ceil(x) 返回数字的上入整数,如math.ceil(4.1) 返回 5
cmp(x, y) 如果 x < y 返回 -1, 如果 x == y 返回 0, 如果 x > y 返回 1
exp(x) 返回e的x次幂(ex),如math.exp(1) 返回2.718281828459045
fabs(x) 以浮点数形式返回数字的绝对值,如math.fabs(-10) 返回10.0
floor(x) 返回数字的下舍整数,如math.floor(4.9)返回 4
log(x) 如math.log(math.e)返回1.0,math.log(100,10)返回2.0
log10(x) 返回以10为基数的x的对数,如math.log10(100)返回 2.0
max(x1, x2,...) 返回给定参数的最大值,参数可以为序列。
min(x1, x2,...) 返回给定参数的最小值,参数可以为序列。
modf(x) 返回x的整数部分与小数部分,两部分的数值符号与x相同,整数部分以浮点型表示。
pow(x, y) x**y 运算后的值。
round(x [,n]) 返回浮点数x的四舍五入值,如给出n值,则代表舍入到小数点后的位数。
sqrt(x) 返回数字x的平方根
2.time库:
import time
time.time():
获取现在时间
时间就是从格林威治时间1970年1月1日0时0分0秒至今的秒数
常用于计算代码运行的时间
#查看代码运行的时间
t1=time.time()
test_sum=sum(range(0,1000))
t2=time.time()
print(test_sum)
print(t2-t1)#这个就是从0加到1000,这个sum函数运行的时间
ctime(time_stamp):
将一个时间戳转化为字符串的形式
time.ctime(time.time())
localtime(time_stamp):
将一个时间戳转化为当地结构化时间
struct_time=time.localtime(152200)
'''
struct_time中的参数
tm_year:年
tm_mon:月
tm_mady:日
tm_hour:小时
tm_min:分钟
tm_soc:秒
tm_wday:周几(0表示周一)
tm_yday:一年中的第几天
tm_isdst:夏令时
'''
这些参数可以直接调用
struct_time.tm_year#可以直接得到year
结构化时间:strptime(string,format):
一般是为了方便机器理解
格式化时间:strftime(format,struct_time):
为了方便人理解
time_str="2008-01-01 00:00:01"
struct_time=time.strptime(time_str,"%Y-%m-%d %H:%M:%S")
#此时的struct_time就是一个按照foramt格式的结构化时间
time_now=time.strftime("%Y%m%d-%H:%M%S",struct_time)
#此时的time_now就是按照foamat格式的格式化时间
sleep():
让代码强制休息一段时间
常用于检测上下游的数据:A->B->C
t1=time.time()
test_sum=sum(range(0,1000))
time.sleep(tm)#睡眠tm秒
t2=time.time()
print(test_sum)
print(t2-t1)#此时的结果就会加上这tm秒
3.re库:
用于字符串的匹配的python标准库
利用了正则表达式来对字符串操作匹配:
'.'代表任意的字符
'\d'代表数字
'+'代表匹配一个模式从0次到无数次
import re
re.search(pattern,string,flags=0):#贪婪匹配
扫描整个字符串并返回成功的第一个匹配
flags:
标志位,用于控制正则表达式的匹配方式,
如是否区分大小写,多行匹配等
phone_string="我是小明,我的手机号是123456789"
x=re.search('\d+',phone_string)
print(x)
'''
print(x)的结果为 re.Match object: span=(11,20)#左闭右开
print(x.span())的结果为(11,20)
print(x.match)的结果为 123456789
print(phone_string[11:20])的结果为 123456789
'''
re.match(pattern,string,flags=0):
尝试从字符串的起始开始匹配,如果不是在起始匹配到,那么返回 None
phone_string="我是小明,我的手机号是123456789"
x=re.match('\d+',phone_string)
print(x)#返回值是None
phone_string="123456789我是小明,我的手机号是"
x=re.match('\d+',phone_string)
print(x.amtch)#返回值是123456789
re.sub(pattern,repl,string,count=0,flags=0):
替换字符串中的某些模式
pattern是被替换的字符串,repl是替换的字符串,string是母串
count是模式替换的最大次数,0为默认值代表替换所有匹配,1就是替换第一次
phone_string="我是小明,我的手机号是123456789"
print(re.sub('我','他',phone_string))
#结果就是他是小明,他的手机号是123456789
phone_string="我是小明,我的手机号是123456789"
print(re.sub('\d+','123',phone_string))
或者
print(re.sub('123456789','123',phone_string))
#结果就是他是小明,他的手机号是123
re.findall(pattern,string,flags=0):
找到满足正则表达式pattern的所有字串,返回一个列表
word_string="虎头蛇尾、牛头马面、虎口脱险"
re.findall('虎.{3}',word_string)
#返回的结果是['虎头蛇尾','虎口脱险']
Numpy库
Numpy:用来专门处理多维数值数组的工具包
Numpy中数组中的所有元素类型必须相同
优势:
运算速度快,底层是用C来实现的
支持并行化计算/向量化计算
Numpy中的 array 为静态类型,而列表为动态类型
有着丰富的内置函数
方便表达多维的向量
导入:import numpy as np
example_array=np.array([1,'222',True])
#example_array为 '1','222','True'
#文件的读入
机器学习中使用np.loadtxt()可以高效的导入数据,np.loadtxt()适合.txt文件和.csv文件。但是它默认读取float类型的值。
numpy.loadtxt(
fname, dtype=, comments='#',
delimiter=None, converters=None,
skiprows=0, usecols=None, unpack=False, ndmin=0)
'''
fname要读取的文件、文件名、或生成器。
dtype数据类型,默认float。
'''
#comments注释:
如果行中出现有comment的值,那在读取时就会跳过该行。
#delimiter分隔符,默认是空格。
#skiprows跳过前几行读取,默认是0,必须是int整型。
#usecols要读取哪些列,0是第一列。例如,usecols = (1,4,5)将提取第2,第5和第6列。默认读取所有列。
#unpack如果为True,将按列读取。
[['伤感自拍' '官宣表白' '秀闺蜜照' '睡前自拍' '情侣离别']
['半身风雨半身伤' '我是檐上三寸雪' '含娇含笑' '南风知我意' '南风未起']
['半句别恨半心凉' '你是人间惊鸿客' '宿翠残红窈窕' '吹梦到西州' '念你成疾']]
['伤感自拍' '官宣表白' '秀闺蜜照' '睡前自拍' '情侣离别'] ['半身风雨半身伤' '我是檐上三寸雪' '含娇含笑' '南风知我意' '南风未起']
#coverters
# 介绍converters参数, 这个是对数据进行预处理的参数
#我们可以先定义一个函数, 这里的converters是一个字典, 表示第1列使用函数func来进行预处理
def func(x):
return int(x)+1
a = np.loadtxt('out1.txt',dtype=int,delimiter=' ',converters={1:func})
print(a)
#numpy数组的创建:
通过python列表来创建:
可选关键字 dtype,可以指定创建的类型
列表中的元素必须是同一类型的
可以输入嵌套列表的方式来创造多维数组
float_array= np.array([1,2,3],dtype='float')
float_array.shape为(1,3)
#创建值全为0的数组:
zero_array=np.zeros(5)#此时为1x5的一个0数组
zero_array=np.zeros([5,5])#此时为5x5的一个0数组
#创建值全为1的数组:
one_array=np.ones((2,5))
#创建全为6的数组:
full_array=np.full((2,5),6)
#创建全为number的数组:
full_array=np.full((行,列),number)
#等距离创建0——1之间,一共count个数的数组:
line_array=np.linspace(0,1,count)#一定是均分
#创建一个0——10,步长为1的数组:
与range相似
np.arange(start,stop,step)
start默认为0
step,步长就是间隔,默认为1
arange_array=np.arange(0,11,1)#左闭右开
'''
结果为:[0 1 2 3 4 5 6 7 8 9 10]
'''
np.linspace(start = 0, stop = 100, num = 5)
'''
间隔起始点、终止端,以及指定分隔值总数(包括起始点和终止点);
num,为生成的个数,会平分从start到end
endpoint 参数决定终止值(stop参数指定)是否被包含在结果数组中。如果 endpoint = True, 结果中包括终止值,反之不包括。缺省为True。
dtype 参数决定输出数组的数据类型。如果不指定,python基于其他参数值推断数据类型。如果需要可以显示指定,参数值为NumPy 和 Python支持的任意数据类型。
'''
#创造一个0——1之间,2x2的随机数组:
np.random.random([2,2])
np.random.seed()的作用:使得随机数据可预测。
当我们设置相同的seed,每次生成的随机数相同。如果不设置seed,则每次会生成不同的随机数
#创造一个0——5之间,2x2的随机整数数组:
np.random.randint(0,5,(2,2))
#给定一个1x10的数组,创建一个从此数组中随机采样的3x3数组
可以有重复的数字
arange_array=np.arange(1,10,1)
np.random.choice(arrange_array,(3,3))
#创造一个均值为0,标准差为1的正态分布数组,形状为3x2:
np.random.normal(0,1,(3,2))
numpy.random.rand(d0,d1,…,dn)
rand函数根据给定维度生成[0,1)之间的数据,包含0,不包含1
dn表格每个维度
np.random.rand(1):表示生成一个一维的数
rand(1,2):生成二维的数
rand(1,2,3):生成三维的数
rnad(2,2,3):生成一个三位数组,2代表有两个二维数组,2代表有两个一维数组,3代表一维数组中有三个数
rnad(3):仅仅会生成一个有三个随机数的一位数组
返回值为指定维度的array
numpy.random.randn(d0,d1,…,dn)
randn函数返回一个或一组样本,具有标准正态分布。
dn表格每个维度
返回值为指定维度的array
np.random.randn() # 当没有参数时,返回单个数据
#数组的属性:
1.查看数组类型:
array.dtype
2.查看各个维度的大小:
查看维度个数:ndim
查看维度的大小:shape
查看数据总个数:size
array=np.random.randint(0,100,(3,3))
array.ndim#结果为2
array.shape#结果为(3,3)
array.size#结果为9
#数组的索引与切片:
array[2]
array[2][3]
获取子数组:
array[start:stop:step]
start不被指定时从0开始
stop不被指定时默认到最后一位
step不指定默认为1
可以用列表的方式表示组合索引
都是左闭右开:
#获取索引stop之前的元素:
array[:stop]
#获取索引start之后的元素:
array[start:]
#获取索引start到stop-1索引的元素:
array[start:stop]
#每隔一位获取一位元素,结果为[0,2,4,6,8]:
array[::2]
#获取从第start位索引到倒数第stop+1位的索引:
array[start:-stop]
#倒叙获取所有的元素:
array[::-1]
#获取第1,3,9个元素,只针对于一维数组:
array[[1,3,9]]
#获取二维数组中的元素,不同维度之间用逗号分隔,同一纬度用冒号分隔:
array=np.array([[0,1,2,3,4],[5,6,7,8,9],[10,11,12,13,14]])
array[:2,:2]
'''
获取二维数组中的前两行前两列,结果为
0 1
5 6
'''
#对所有的行进行倒序输出:
array[::-1,:]
#获取首行:
array[0,:]
#获取首列:
array[:,0]
#获取首行的0,1,4个元素:
array[0,[0,1,4]]
#数组的修改与拷贝:
索引和切片:
切片获得的子数组是视图不是副本
创建副本需要用copy命令
#将首行全部改为1:
array[0,:]=np.ones(5)
#对数组进行拷贝:
array_copy=aray.copy()
#对拷贝数组进行修改:
array_copy[0,:]=np.zeros(5)
#数组的特殊操作:
array.np.arange(6)
1.变形:
array.reshape()
变形不能超过最大的维度:
1× 6:最大的维度是 6
#将1x6变成2x3:
array.reshape((2,3))
2.转置:
将行 列进行转化
array.T
array= np.arange(6).reshape((2,3))
print(array.T)#此时行列互换
3.一维数组的拼接和分裂:
拼接:
row_concatenate=np.concatenate([array1,array2])
#将array1与array2进行拼接
分裂:
x1,x2,x3=np.split(row_concate,[1,3])
#分裂点为左闭右开,从1 2处断开,分成三段 [0] [1 2] [3 4 5 6]
4.多维数组的拼接和分裂:
array1=np.arange(6).reshape((2,3))
array2=np.arange(6,12,1).reshape((2,3))
拼接:
array_row=np.concatenate([array1,array2],axis=0)
#对行维度进行拼接,就是上下堆积
array_col=np.concatenate([array1,array2],axis=1)
#对列维度进行拼接,就是左右堆积
分裂:
x1,x2,x3=np.split(array_row,[1,2].axis=0)
#对行维度进行分裂,[0] [1] [2 3 4 5]
x1,x2,x3=np.split(array_col,[1,2],sxis=1)
#对列维度进行分裂
#vstack()和hstack():拼接的数组的维度必须一致
np.vstack():对行维度,上下数组堆叠,形成新的更高维数组,vstack()要求第二维度也必须一样
np.hstack():对列维度,左右相拼,维度不会增加
5.重新随机排序
np.random.shuffle(x) :在原数组上进行,改变自身序列,无返回值。
np.random…permutation(x) :不在原数组上进行,返回新的数组,不改变自身数组。
#Numpy数组的计算方式:
相同维度:
一维:
x1= np,arange(10)
x2= np.arange(10,20)
print(x1+x2)#对应index的元素相加
二维:
x1= np.arange(10).reshape(2,5)
x2= np.arange(10,20).reshape(2,5)
print(x1+x2)#对应index的元素相加
不同维度:广播机制
两个数组维度不同,那么维度较小的数组会在最左边的维度补1
如果两个数组任何维度都不匹配,那么数组会沿着维度为1的维度扩展匹配另一个数组的形状,会自身复制
#Numpy数组的内置计算函数:
#取绝对值:
np.abs()
#计算和:
np.sum():
np.sum(array)#将所有元素相加
np.sum(array,axis=0)#将行维度,即将数组上下相加
np.sum(array,axis=1)#将列维度,即将数组左右相加
#计算平均值
np.mean():
np.mean(array)#对整个数组取平均值
np.mean(array,axis=0)#将行维度,即将数组上下相加取平均值
np.mean(array,axis=1)#将列维度,即将数组左右相加取平均值
#计算标准差
np.std()
#取最值:
np.max():
np.max(array,axis=0)#对行维度相中的数取最大值
np.max(array,axis=1)#对列维度相中的数取最大值
np.min():
np.max(array,axis=0)#对行维度相中的数取最小值
np.max(array,axis=1)#对列维度相中的数取最小值
#计算最值的索引
np.argmax():
np.argmax(array,axis=0)#取最大的行
np.argmax(array,axis=1)#取最大的列
np.argmin():
np.argmin(array,axis=0)#取最小的行
np.argmin(array,axis=1)#取最小的列
#矩阵运算
np.dot():
1.向量的内积运算:也就是一维的矩阵,需要保证两个向量包含的元素个数是相同的
result=np.dot(x,y)
将向量中对应元素相乘,再相加所得。即普通的向量乘法运算
x1*y1+x2*y2+......+xn*yn
2.矩阵乘法运算:
x为 m×n 阶矩阵,y为 n×p 阶矩阵,则相乘的结果 result 为 m×p 阶矩阵。
#两者不相等,矩阵乘法不满足交换律
3.矩阵与向量乘法的运算:进行运算时,会首先将后面一项进行自动转置操作,之后再进行乘法运算。
#比较运算:
num_array=np.array([0,1,2,3])
1.直接比较:
num_array <= 2
#结果为一个元素为布尔类型的数组 array([True,True,True,Flase])
num_array >0 & num_array<2
#结果为 array([False,True,False,False])
2.取出对应的值:
num_array[num_array <= 2]
#结果为对应元素的数组 array[0,1,2]
num_array[(num_array >0) & (num_array<2)]
#结果为 array([1])
3.统计个数:
np.count_nonzero()#统计非零项的个数
np.count_nonzero(num_array < 2)#结果为2
4.判断是否存在:
np.any()#判断是否会成立,若存在则返回True,否则Flase
np.any(num_array<0)#结果为Flase
5.判断是否都成立:
np.all()#判断是否都成立,如果都成立则True,否则Flase
np.all(num_array < 3)#结果为False
Pandas
Pandas:
基于Numpy的数据分析工具,主要用于处理表格数据
主要用于数据分析,数据预处理,缺失值查询,对于混杂数据的处理
Pandas与Excle的区别:
Pandas速度更快,大量数据
操作更灵活,拥有大量内置函数,也可以自定义函数来进行数据操作和分析
#基本数据结构:
series:
用于储存一列数据以及对应的索引
dataframe:
用于存储多行多列的数据
import pandas as pd
#Series:
series由索引组成:
pandas.Series(data,index,dtype,name,copy)
#data:一组数据(array)数据类型
#index:数据索引标签,如果不指定,默认从0开始,可以自己设定
#dtype:数据类型,默认会自己判断
#name:设置名称
#copy:拷贝数据,默认为Flase
import pandas as pd
a=[1,2,3]
myvar= pd.Series(a)
print(myvar)
'''
0 1
1 2
2 3
dtype: int64
'''
print(myvar[1])#此时myvar为一个列数组
a=["G","R","W"]
myvar=pd.Series(a,index=["X","Y","Z"])
print(myvar)
'''
X G
Y R
Z W
dtype: object
'''
print(myvar["Y"])#结果为:R
#字典创建
#我们也可以使用 key/value 对象,类似字典来创建 Series,此时key就是索引,而value就是值:
sites = {1: "Google", 2: "Runoob", 3: "Wiki"}
myvar = pd.Series(sites)
print(myvar)
'''
1 Google
2 Runoob
3 Wiki
'''
#如果我们只需要字典中的一部分数据,只需要指定需要数据的索引即可:
myvar= pd.Series(sites,index=[1,2])
print(myvar)
'''
1 Google
2 Runoob
'''
#设置name 名称参数:
sites = {1: "Google", 2: "Runoob", 3: "Wiki"}
myvar = pd.Series(sites, index = [1, 2], name="RUNOOB-Series-TEST" )
print(myvar)
'''
1 Google
2 Runoob
Name: RUNOOB-Series-Test,dtype:object
'''
#DataFrame:
DataFrame,是一个表格型的数据结构,它含有一组有序的列,每一列都可以是不同的值类型(数值、字符串、布尔型值)。DataFrame既有行索引也有列索引,可以看作由Series组成的字典(共用一个索引)
#构造方法:
pandas.DataFrame(data,index,columns,dtype,copy)
'''
data: 一组数据(ndarray,series,map,lists,dict)
indx: 索引值/行标签
columns: 列标签,默认为RangeIndex(0,1,2...,n)
dtype: 数据类型
copy:拷贝数据,默认为False
'''
data = [['Google',10],['Runoob',12],['Wiki',13]]
df= pd.DataFrame(data,columns=['Site','Age'],dtype=float)
print(df)
'''
Site Age
0 Google 10.0
1 Runoob 12.0
2 Wiki 13.0
'''
data = {'Site':['Google', 'Runoob', 'Wiki'], 'Age':[10, 12, 13]}
df = pd.DataFrame(data)
print (df)
'''
Site Age
0 Google 10.0
1 Runoob 12.0
2 Wiki 13.0
'''
data = [{'a': 1, 'b': 2},{'a': 5, 'b': 10, 'c': 20}]
df = pd.DataFrame(data)
print (df)
'''
a b c
0 1 2 NaN
1 5 10 20.0
'''
#没有对应的部分数据为NaN
#可以使用loc返回指定行的数据,索引值默认为0
data = {
"calories": [420, 380, 390],
"duration": [50, 40, 45]
}
df = pd.DataFrame(data)
print(df)
'''
calories duration
0 420 50
1 380 40
2 390 45
'''
print(df.loc[0])
'''
calories 420
duration 50
Name: 0, dtype: int64
'''
#返回的结果其实是一个Pandas Series数据
#也可以返回多行数据:
#使用 [[ ... ]] 格式,... 为各行的索引,以逗号隔开
print(df.loc[[0,1]])
'''
calories duration
0 420 50
1 380 40
'''
#返回结果其实就是一个 Pandas DataFrame 数据。
data = {
"calories": [420, 380, 390],
"duration": [50, 40, 45]
}
df = pd.DataFrame(data, index = ["day1", "day2", "day3"])
print(df.loc["day2"])
'''
calories 380
duration 40
Name: day2, dtype: int64
'''
#Pandas CSV文件:
CSV(Comma-Separated Values,逗号分隔值,有时也称为字符分隔值,因为分隔字符也可以不是逗号),其文件以纯文本形式存储表格数据(数字和文本)。
CSV 是一种通用的、相对简单的文件格式,被用户、商业和科学广泛应用。
import pandas as pd
df= pd.read_csv('nba.csv')
print(df.to_string())
#to_string() 用于返回 DataFrame 类型的数据,如果不使用该函数,则输出结果为数据的前面 5 行和末尾 5 行,中间部分以 ... 代替。
#to_csv() 方法将 DataFrame 存储为 csv 文件:
df.to_csv('site.csv')
#数据处理:
head(n):
用于读取前面的几行,默认为5
print(df.head())
tail(n):
用于读取尾部的几行,默认为5,空行返回NaN
print(df.tail())
info():
返回表格的一些基本信息
print(df.info())
'''
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 458 entries, 0 to 457 # 行数,458 行,第一行编号为 0
Data columns (total 9 columns): # 列数,9列
# Column Non-Null Count Dtype # 各列的数据类型
--- ------ -------------- -----
0 Name 457 non-null object
1 Team 457 non-null object
2 Number 457 non-null float64
3 Position 457 non-null object
4 Age 457 non-null float64
5 Height 457 non-null object
6 Weight 457 non-null float64
7 College 373 non-null object # non-null,意思为非空的数据
8 Salary 446 non-null float64
dtypes: float64(4), object(5) # 类型
'''
#常用函数:
pd.read_csv(filename) 读取 CSV 文件;
pd.read_excel(filename) 读取 Excel 文件;
pd.read_sql(query, connection_object) 从 SQL 数据库读取数据;
pd.read_json(json_string) 从 JSON 字符串中读取数据;
pd.read_html(url) 从 HTML 页面中读取数据。
df.head(n) 显示前 n 行数据;
df.tail(n) 显示后 n 行数据;
df.info() 显示数据的信息,包括列名、数据类型、缺失值等;
df.describe() 显示数据的基本统计信息,包括均值、方差、最大值、最小值等;
df.shape 显示数据的行数和列数。
Matplotlib
matplotlib是一种数据可视化的工具,自由生成点线图、直方图等各种的图形
前置准备:
交互环境:%matplotlib inline#直接将图形文件嵌入在单元的输出模块中
#导入包:
import matplotlib.pyplot as plt
%matplotlib inline
plt.plot():用于绘制线图和散点图
# 画单条线
plot([x], y, [fmt], *, data=None, **kwargs)
# 画多条线
plot([x], y, [fmt], [x2], y2, [fmt2], ..., **kwargs)
'''
x, y:点或线的节点,x 为 x 轴数据,y 为 y 轴数据,数据可以列表或数组。
传入参数的时候注意要X轴在一个数组,Y轴在一个数组
如果我们不指定 x 轴上的点,则 x 会根据 y 的值来设置为 0, 1, 2, 3..N-1。
fmt:可选,定义基本格式(如颜色、标记和线条样式)。
'o':为实心的圈,bo为蓝色实心圈
'r+':红色+号
'x':为X号
颜色字符:'b' 蓝色,'m' 洋红色,'g' 绿色,'y' 黄色,'r' 红色,'k' 黑色,'w' 白色,'c' 青绿色,'#008000' RGB 颜色符串。多条曲线不指定颜色时,会自动选择不同颜色。
线型参数:'‐' 实线,'‐‐' 破折线,'‐.' 点划线,':' 虚线。
标记字符:'.' 点标记,',' 像素标记(极小点),'o' 实心圈标记,'v' 倒三角标记,'^' 上三角标记,'>' 右三角标记,'<' 左三角标记...等等。
如果我们只想绘制两个坐标点,而不是一条线,可以使用 o 参数,表示一个实心圈的标记。
'o:r' 表示实心圆标记,:表示虚线,r表示红色
**kwargs:可选,用在二维平面图上,设置指定属性,如标签,线的宽度等。
ms:代表标记大小
自定义线的类型
linestyle:简写为ls
'solid' (默认) '-' 实线
'dotted' ':' 点虚线
'dashed' '--' 破折线
'dashdot' '-.' 点划线
'None' '' 或 ' ' 不画线
线的颜色用color,简写c
'r' 红色
'g' 绿色
'b' 蓝色
'c' 青色
'm' 品红
'y' 黄色
'k' 黑色
'w' 白色
线的宽度用linewidth,简写lw
可以是int,float
lw='12.5'
plot() 方法中可以包含多对 x,y 值来绘制多条线。
y1 = np.array([3, 7, 5, 9])
y2 = np.array([6, 2, 13, 10])
plt.plot(y1)
plt.plot(y2)
'''
#xlabel() 和 ylabel() 方法来设置 x 轴和 y 轴的标签。
plt.xlabel("x - label")
plt.ylabel("y - label")
#title() 方法来设置标题。
plt.title("RUNOOB TEST TITLE")
机器学习
有监督学习:有确定的答案
分类任务:目标为离散值变量
回归任务:目标为连续值变量
无监督学习:没有确定的答案
聚类任务(进行归类):无目标,需要根据特征进行归类
半监督学习:一半有答案,一半没有答案
机器学习的流程:
训练:
从现有数据集进行学习数据的已有模式,生成模型
预测:
基于训练好的模型,预测未来的数据
#所以在拿到数据的时候,我们首先要进行划分训练集、验证集和测试集
常用的算法:
分类:
逻辑回归、支持向量机、神经网络、随机森林、Boosting方法、朴素贝叶斯
回归:
线性回归、决策树回归、随机森林回归
聚类:
Kmeans聚类
损失函数:算法总是朝着使得损失函数最小的方向来迭代优化
优化的方法,一般是梯度下降法,由此找到参数最优解
梯度下降法就是通过迭代的方法来找到损失函数最小的点,每一次迈一步,方向是函数的负梯度方向,一直到山底
交叉验证:
简单交叉验证
S折交叉验证
留一交叉验证
过拟合与欠拟合:
模型学习的太多,出现过拟合,导致学习的规律只适用于训练集
如果学的太少,那么就是欠拟合现象
算法基础:
线性回归:回归算法的基础
逻辑回归:线性分类算法基础
决策树:基础的树形结构,在分类问题上,根据特征进行 if-else判断,在各个节点上通过信息增益等指标来对节点进行分裂,最后形成树。
#可读性强,逻辑接近人脑
#类别特征无需额外处理
#速度较快
SKLearn
涵盖分类、回归、聚类、降维、模型选择、数据处理