pd.ExcelFile('file.xls') 读取Excel文件

4.3万
0
2023-08-01 16:32:23
6
投币
收藏
1
主要发布:数学思维与文化、少儿编程、发明创造、《新概念英语》背诵相关视频
3836.9万播放
简介
对类进行数理化生成对象。并用对象调用方法类输出数据
01:24
复习people类的定义
01:40
加载类之后生成对象并调用类里面的方法
00:53
Python 同样支持类的继承,如果一种语言不支持继承,类就没有什么意义
00:16
class DerivedClassName(BaseClassName1) 派生类定义
00:30
BaseClassName(基类名称)必须与派生类定义在一个作用域内
00:17
除了类,还可以用表达式,基类定义在另一个模块中时这一点非常有用
00:23
class DerivedClassName(modname.BaseClassName)
00:25
class student(people)
00:49
单继承模式,只有一个父类
00:19
student 类的构造函数
00:45
student 类中覆写父类的方法
00:55
加载子类 student 到当前运行环境中
00:26
生成一个子类 student 的对象并调用方法
00:44
单继承 student 类总结
00:51
重启内核后直接加载 student 类不成功
00:55
先加载 people 再加载 student 继承自 people 没有问题
00:21
Python 同样有限的支持多继承形式。多继承的类定义形如下例
00:16
class DerivedClassName(Base1, Base2, Base3)
00:19
多重继承的语法含义和注意事项
00:20
若是父类中有相同的方法名,而在子类使用时未指定。Python 从左至右搜索 即方法在子类中未找到时,从左到右查找父类中是否包含方法
00:32
定义 speaker 类,多重继承之前的准备
00:22
speaker 类的详细定义
00:48
class sample(speaker,student) 多重继承
00:37
sample类的详细定义
01:01
sample 类生成 test 对象。使用对象查看器查看
00:52
方法名同,默认调用的是在括号中排前面的父类的方法
00:38
如果你的父类方法的功能不能满足你的需求,你可以在子类重写你父类的方法
00:14
class Parent 定义一个父类
00:16
class Child(Parent) 定义子类
00:17
c = Child() 子类实例
00:11
生成父类和子类之后,再生成子类的实例
00:24
c.myMethod() # 子类调用重写方法
00:24
x = super(Child,c)
01:03
super(Child,c).myMethod() # 用子类对象调用父类已被覆盖的方法
00:26
super() 函数是用于调用父类(超类)的一个方法
00:14
super() 生成了一个父类的对象
00:39
查看 super() 函数
01:37
super()函数生成的是父类对象,但不知道父类名字
00:34
一个类派生自两个父类还是可以使用 super() 生成对象
00:56
此时的父类对象y调用的仍然是speaker()类里面的speak()方法
01:11
Python 子类继承父类构造函数说明
00:48
如果在子类中需要父类的构造方法就需要显式地调用父类的构造方法。或者重写父类的构造方法
00:41
子类不重写 __init__,实例化子类时,会自动调用父类定义的 __init__
01:11
class Father(object)
01:09
def getName(self)
00:23
class Son(Father)
00:13
def getName(self)
00:45
生成 Son 对象,代码分析
00:53
加载类到当前环境中,生成 Son 对象
00:43
通过变量管理器查看 son 对象里面的属性和方法
00:45
深度分析 Son 类的方法
01:53
如果重写了__init__ 时,实例化子类,就不会调用父类已经定义的 __init__
00:30
def __init__(self, name) 在子类中覆写了 __init__() 构造方法
00:22
重新加载父类和子类。此时的子类已经被改写
00:23
son=Son('runoob') 调用子类中的构造方法 __init__()
01:03
如果重写了__init__ 时,要继承父类的构造方法,可以使用 super 关键字
00:13
super(子类,self).__init__(参数1,参数2,....)
00:25
父类名称.__init__(self,参数1,参数2,...)
00:17
class Father(object) 父类定义
00:28
class Son(Father) 子类定义
00:25
super(Son, self).__init__(name) 子类定义中调用父类构造方法
00:37
class Son(Father) 子类定义详细介绍
01:00
再次加载父类和子类
00:25
子类中调用了父类的构造方法
01:27
类属性与方法,详细介绍
00:33
类的属性介绍
00:41
类的属性分为公开属性和私有属性
00:30
公开属性举例。math.pi
00:26
私有属性不能通过类名、对象名访问
00:18
__private_attrs:两个下划线开头,声明该属性为私有,不能在类的外部被使用或直接访问
00:21
在类内部的方法中使用时 self.__private_attrs
00:18
类的方法。方法就是一定的行为或操作
00:41
在类的内部,使用 def 关键字来定义一个方法
00:08
与一般函数定义不同,类方法必须包含参数 self,且为第一个参数,self 代表的是类的实例
00:13
self 的名字并不是规定死的,也可以使用 this,但是最好还是按照约定是用 self
00:16
每个 Python 类方法都必须使用 self 参数,并且是第一个参数
00:29
为什么使用 self 标示类方法
00:53
class JustCounter
00:24
def count(self) 定义类方法,给私有、共有变量增加数值
00:42
加载 JustCounter 类到当前运行环境
00:30
使用 JustCounter 类生成 counter 对象
00:23
生成的counter对象调用count()方法输出变量
00:31
counter.publicCount 共有属性通过对象直接查询
00:35
print (counter.__secretCount) 报错,实例不能访问私有变量
00:27
JustCounter.publicCount 通过类直接方法公共属性会得到什么结果
00:39
JustCounter.publicCount 可以访问,不会报错。但结果是零,表示类的初始值
00:43
从隐私、数据安全角度考虑属性分类
01:19
JustCounter 生成对象调用方法进行计数
01:00
类的私有方法实例如下
00:25
class Site 定义一个 Site 类
00:22
def __init__(self, name, url) 对公有、私有属性进行初始化
00:28
def who(self) 输出网站名称和链接地址
00:24
def __foo(self) 私有方法,输出一个字符串
00:17
def __foo(self) 即使不使用对象的属性或方法,类方法的第一参数一定要是 self
00:31
class Site 加载到当前运行环境中
00:18
x = Site('菜鸟教程', 'www.runoob.com') 生成 Site 类的对象
00:28
使用变量管理器查看对象的方法
01:01
x.who() # 正常输出
00:24
x.foo() # 正常输出
00:24
x.__foo() # 报错
00:28
类的专有方法(全部都是私有方法)
00:39
__init__ : 构造方法,在生成对象时调用
00:55
__del__ : 析构方法,释放对象时使用
00:33
为什么是 del 这样的结构。主要是调用了 del 来删除对象
00:38
__repr__ : 打印,转换
00:09
__setitem__ : 按照索引赋值
00:12
__getitem__ : 按照索引获取值
00:10
__len__ : 获得长度
00:06
__cmp__ : 比较运算
00:24
__call__ : 函数调用
00:09
__add__ : 加运算。 通过这几个专用的私有方法可以实现运算符重载
00:19
__mul__ : 乘运算
00:14
__sub__ : 减运算
00:09
__truediv__ : 除运算
00:11
__mod__ : 求余运算
00:08
__pow__ : 乘方
00:26
运算符重载示例
01:25
字符串乘以浮点数出现类型错误
00:39
Python 支持运算符重载,我们可以对类的专有方法进行重载
00:22
class Vector 定义了 3 个方法。其中两个是专有方法
00:47
def __init__(self, a, b) 初始化类的两个公共属性a,b
00:32
def __str__(self) 功能介绍
00:35
def __add__(self,other) 对象相加介绍
00:54
加载 Vector 类到当前运行环境中
00:22
生成两个对象并进行初始化
00:31
加法运算符重载成功
00:32
vx=v1+v2 生成新的变量
01:29
变量名 和 print() 输出结果不同
01:12
Python 3 命名空间和作用域
00:27
命名空间(Namespace)是从名称到对象的映射,大部分的命名空间都是通过 Python 字典来实现的
00:17
命名空间提供了在项目中避免名字冲突的一种方法
00:30
软件开发人员多、规模大,用命名空间来解决冲突问题
01:19
各个命名空间是独立的,没有任何关系的
00:09
所以一个命名空间中不能有重名,但不同的命名空间是可以重名而没有任何影响
00:11
一个文件夹(目录)中可以包含多个文件夹,每个文件夹中不能有相同的文件名
00:23
Python 中有 3 种不同的命名空间
00:14
三种命名空间的名称
00:19
内置名称(built-in names)
00:21
内置名称举例
00:47
全局名称(global names)
00:21
导入模块之后就可以全局自由使用
00:50
局部名称(local names)
00:23
函数中产生的变量、名字等同主程序变量区分开
01:36
命名空间查找顺序
00:28
假设我们要使用变量 runoob,则 Python 的查找顺序
00:36
局部的命名空间,全局命名空间,内置命名空间
00:50
分类分区域查找,更有利于模块化编程
01:09
对 max 赋值。生成一个局部变量,与 max 函数同名
01:06
变量管理器中看到有max变量
00:35
当前的局部命名空间中有个max,与内置命名空间的max重名
00:43
如何设计一个实验来验证,是在两个命名空间中都有max还是新的max覆盖了内置函数?
00:23
删除局部的max变量,原来的内置函数还是可以调用
00:30
如果找不到变量 runoob,它将放弃查找并引发一个 NameError 异常
00:22
NameError:name 'runoob' is not defined
00:18
命名空间的生命周期
00:34
命名空间的生命周期取决于对象的作用域,如果对象执行完成,则该命名空间的生命周期就结束
00:15
因此,我们无法从外部命名空间访问内部命名空间的对象
00:12
函数内外部变量不会有相互影响
00:28
def some_func() 定义函数内部的局部变量
00:20
def some_inner_func() 函数内部还有变量
00:16
层层内嵌生成局部变量
00:24
非常不推荐函数中又嵌入函数的设计方法
00:23
作用域就是一个 Python 程序可以直接访问命名空间的正文区域
00:20
从内到外依次访问所有的作用域直到找到,否则会报未定义的错误
00:16
Python 是解释型语言,遇到变量、函数名就会去查找
00:33
Python 中,程序的变量并不是在哪个位置都可以访问的
00:17
访问权限决定于这个变量是在哪里赋值的
00:31
变量的作用域决定了在哪一部分程序可以访问哪个特定的变量名称
00:11
变量有严格的访问规则,并非随意访问
00:22
Python的作用域一共有 4 种
00:19
L(Local):最内层,包含局部变量,比如一个函数-方法内部
00:15
函数内部的变量与外部无关
00:27
E(Enclosing):包含了非局部(non-local)也非全局(non-global)的变量
00:13
比如两个嵌套函数,一个函数(或类) A 里面又包含了一个函数 B
00:22
G(Global):当前脚本的最外层,比如当前模块的全局变量
00:15
B(Built-in): 包含了内建的变量-关键字等。最后被搜索
00:12
以 max 为例来说明内置变量可以被用户修改
00:34
max 内置函数名称,也可以赋值
00:28
规则顺序: L – E – G – B
00:19
在局部找不到,便会去局部外的局部找(例如闭包),再找不到就会去全局找,再者去内置中找
00:20
g_count = 0 # 全局作用域
00:20
def outer() 闭包函数外的函数中
00:21
def inner() 局部作用域
00:17
内置作用域是通过一个名为 builtin 的标准模块来实现
00:13
但是这个变量名自身并没有放入内置作用域内,所以必须导入这个文件才能够使用它
00:13
在 Python3.0 中,可以使用以下的代码来查看到底预定义了哪些变量
00:11
导入 builtins 模块,展示其中的名字
00:15
builtins 包含常见错误和内置函数的名字
01:04
int 处于内置作用域。可以被修改并且最后被查找
00:12
int 内置函数可以作为本地变量名称
00:29
变量管理器可以看出来,int 是一个变量而不是函数
00:31
保留字不能随意使用。内置函数名称可以自由使用
00:34
Python 中只有模块(module),类(class)以及函数(def、lambda)才会引入新的作用域
00:13
其它的代码块(如 if elif else、try except、for while等)不会引入新的作用域
00:16
也就是说这些语句内定义的变量,外部也可以访问
00:25
if 结构中生成的变量,外部可以正常访问
00:23
del 删除 msg 变量,没有问题
00:17
if 没有给 msg 赋值,变量不存在
00:37
实例中 msg 变量定义在 if 语句块中,但外部还是可以访问的
00:15
如果将 msg 定义在函数中,则它就是局部变量,外部不能访问
00:11
def test() 定义一个函数。包含一个内部变量
00:18
print(msg_inner) 访问失败。找不到变量
00:29
从报错的信息上看,说明了 msg_inner 未定义,无法使用
00:14
因为它是局部变量,只有在函数内可以使用
00:13
内外有别,避免破坏函数的独立性
00:58
全局变量和局部变量,之间的区别和联系
00:12
定义在函数内部的变量拥有一个局部作用域,定义在函数外的拥有全局作用域
00:29
局部变量只能在其被声明的函数内部访问,而全局变量可以在整个程序范围内访问
00:13
调用函数时,所有在函数内声明的变量名称都将被加入到作用域中
00:10
total = 0 # 这是一个全局变量
00:14
def sum( arg1, arg2 )
00:16
total = arg1 + arg2 # total在这里是局部变量
00:32
print ('函数内是局部变量:', total)
00:20
return total 返回计算结果
00:10
sum( 10, 20 ) 调用之后返回结果。输出的是内部变量
00:25
加载变量定义和函数定义
00:22
外部变量还是 0
00:15
双引号换成了单引号,还是正常运行
00:16
print ('函数外是全局变量:', total)
00:31
函数内部直接访问外部的 全局变量。没有语法错误
00:22
运行时发现出错
00:18
UnboundLocalError:local variable 'total' referenced before assignment
00:28
global 和 nonlocal 关键字
00:27
当内部作用域想修改外部作用域的变量时,就要用到 global 和 nonlocal 关键字了
00:13
函数内部不能直接使用全局变量
00:22
以下实例修改全局变量 num
00:12
def fun1() 定义 全局变量 和 相关函数
00:29
定义全局变量,加载到内存中没问题
00:27
在函数内部输出和修改全局变量,没有问题
00:24
函数内部修改了全局变量,外部调用时已经是修改后的数据
00:14
print(num) 外部再输出一次之后观察
00:16
num 已经被修改了
00:13
函数内部的 num 如果不赋值就使用会出现错误
00:16
def fun1() 定义全局变量,定义全局函数
00:24
num 此时是本地变量。必须首先赋值,然后引用
00:20
print(num) 在外部看看变量的情况
00:15
全局变量的数值并没有被函数修改掉
00:21
修改嵌套作用域(enclosing 作用域,外层非全局作用域)中的变量需要 nonlocal 关键字
00:24
def outer() 定义外部函数和变量 num
00:20
def inner() 定义一个内部函数
00:19
将嵌套函数定义加载到内存中。没有任何问题
00:13
outer() 函数的后半部分定义
00:34
对整个函数进行加载操作
00:10
成功修改了 outer() 中的变量
00:49
没有 nonlocal 定义两个新函数
00:19
没有 nonlocal 定义变量,还是正常加载,没有出现问题
00:14
outer() 正常运行,不会出错
00:21
Python 3 标准库概览
00:40
操作系统接口
00:14
os 模块提供了不少与操作系统相关联的函数
00:10
import os 导入 os 库
00:10
返回当前的工作目录
00:16
os.getcwd() 获得当前工作目录
00:28
IDE 上面也有当前工作目录的设置功能
00:22
修改当前的工作目录
00:20
os.chdir('..')解释
00:21
运行之后当前工作目录发生改变
00:13
IDE 上也可以看到当前工作目录发生了改变
00:13
执行系统命令 mkdir 生成新目录
00:13
os.system('mkdir 新目录')
00:17
成功生成了新的目录
00:10
建议使用 import os 风格而非 from os import 星
00:13
这样可以保证随操作系统不同而有所变化的 os.open() 不会覆盖内置函数 open()
00:13
直接导入会覆盖系统内置函数open()
00:31
在使用 os 这样的大型模块时内置的 dir() 和 help() 函数非常有用
00:11
dir() 和 help() 函数可以详细查看模块里面的内容
00:24
os 中有 153 个常量和函数名称
00:34
x = help(os) 获取详细帮助信息
00:42
os 模块总结
00:32
针对日常的文件和目录管理任务,shutil 模块提供了一个易于使用的高级接口
00:10
import shutil
00:10
shutil.copyfile('data.db', 'archive.db')
00:18
类似于命令行直接操作文件
00:23
shutil.move('build executables', 'installdir')
00:11
文件通配符
00:28
glob 模块提供了一个函数用于从目录通配符搜索中生成文件列表
00:14
import glob
00:10
匹配所有的 Python 脚本程序
00:25
命令行参数
00:39
通用工具脚本经常调用命令行参数
00:07
这些命令行参数以链表形式存储于 sys 模块的 argv 变量
00:38
例如在命令行中执行 python demo.py one two three 后可以得到以下输出结果
00:25
import sys 导入 sys 库
00:13
print(sys.argv) 没有任何数据
00:22
错误输出重定向和程序终止
00:33
sys 还有 stdin,stdout 和 stderr 属性
00:24
即使在 stdout 被重定向时,后者也可以用于显示警告和错误信息
00:10
sys.stderr.write('Warning, log file not found starting a new one')
00:18
错误信息直接显示出来
00:12
大多脚本的定向终止都使用 sys.exit()
00:11
查看 sys 模块的名称信息
00:31
sys 模块通过 help() 查看
01:04
正则表达式,又称规则表达式,(Regular Expression,在代码中常简写为regex、regexp或RE)
00:28
是一种文本模式,包括普通字符(例如,a 到 z 之间的字母)和特殊字符(称为 元字符),是计算机科学的一个概念
00:20
正则表达式使用单个字符串来描述、匹配一系列匹配某个句法规则的字符串,通常被用来检索、替换那些符合某个模式(规则)的文本
00:24
正则表达式是对字符串操作的一种逻辑公式
00:19
就是用事先定义好的一些特定字符、及这些特定字符的组合,组成一个 规则字符串
00:13
这个 规则字符串 用来表达对字符串的一种过滤逻辑
00:10
正则表达式的应用场景
00:25
使用正则表达式一次匹配多种字符串
00:51
字符串正则匹配
00:25
re 模块为高级字符串处理提供了正则表达式工具
00:32
对于复杂的匹配和处理,正则表达式提供了简洁、优化的解决方案
00:17
import re 导入 re 库
00:14
dir(re) 分析 re 库中的名字
00:35
help(re) 查看 re 模块帮助信息
01:02
re.findall() 实验效果
00:21
re.findall() 字符串匹配分析
00:36
re.sub() 截取子字符串
00:18
如果只需要简单的功能,应该首先考虑字符串方法,因为它们非常简单,易于阅读和调试
00:18
'tea for too'.replace('too', 'two') 字符串替换
00:14
字符串对象本身包含一些很有用的方法
00:21
正则表达式难度较大一些,可以使用简单方法解决
00:25
math模块为浮点运算提供了对底层C函数库的访问
00:11
底层依然是 C 语言的函数库,只是通过 Python 进行封装
00:24
import math 成功导入 math 库
00:17
使用 cos() 方法和 math.pi 计算余弦值
00:17
math.log(1024, 2)
00:15
访问互联网
00:18
有几个模块用于访问互联网以及处理网络通信协议
00:09
其中最简单的两个是用于处理从 urls 接收的数据的 urllib.request
00:16
以及用于发送电子邮件的 smtplib
00:15
from urllib.request import urlopen
00:14
导入 urlope() 方法成功
00:13
import smtplib 调入邮件协议库
00:17
打开邮件服务器发送邮件之后再关闭
00:27
注意第二个例子需要本地有一个在运行的邮件服务器
00:14
日期和时间
00:19
datetime 模块为日期和时间处理同时提供了简单和复杂的方法
00:17
支持日期和时间算法的同时,实现的重点放在更有效的处理和格式化输出
00:20
该模块还支持时区处理
00:08
dates are easily constructed and formatted
00:21
不同地区日期和时间的使用习惯不同
00:45
from datetime import date
00:10
date 模块中有很多与日期相关的方法
00:29
import datetime 导入 datetime 模块
00:12
now = date.today()
00:20
date() 方法生成日期数据
00:17
date() 方法运行结果分析
00:12
now.strftime() 格式化时间字符串
00:27
now.strftime() 运行结果展示与分析
00:25
dates support calendar arithmetic
00:20
日期数据支持算数运算
00:19
age 是 datetime.timedelta 数据类型
00:30
变量管理器中查看 datetime.timedelta 数据类型
00:22
age类型有多种属性
00:33
数据压缩
00:24
以下模块直接支持通用的数据打包和压缩格式
00:16
zlib 库导入成功
00:08
dir(zlib) 查看zlib库信息
00:23
help(zlib) 帮助信息
00:45
s = b'witch which has which witches wrist watch'
00:20
变量管理器中查看字符串 s
00:19
print(len(s)) 字符串长度是41个字节
00:13
压缩 s 的结果赋值给 t
00:15
变量管理器中查看 t
00:17
print(len(t))检测压缩后的长度
00:13
解压缩并输出字符串
00:20
对压缩后的字符串做解压缩操作成功
00:26
print(zlib.crc32(s)) 获取校验码
00:16
性能度量
00:16
有些用户对了解解决同一问题的不同方法之间的性能差异很感兴趣
00:13
Python 提供了一个度量工具,为这些问题提供了直接答案
00:08
例如,使用元组封装和拆封来交换元素看起来要比使用传统的方法要诱人的多
00:14
timeit 证明了现代的方法更快一些
00:13
from timeit import Timer 导入方法
00:16
Timer('t=a; a=b; b=t', 'a=1; b=2').timeit()
00:23
timeit() 测试成功
00:20
Timer('a,b = b,a', 'a=1; b=2').timeit()
00:12
元组模式交换数据,可以看到测量的结果
00:11
元组交换方式,效率更高
00:17
timeit 检测代码的粒度要细很多
00:13
profile 和 pstats 模块提供了针对更大代码块的时间度量工具
00:20
测试模块
00:20
开发高质量软件的方法之一是为每一个函数开发测试代码
00:11
并且在开发过程中经常进行测试
00:12
doctest模块提供了一个工具,扫描模块并根据程序中内嵌的文档字符串执行测试
00:22
测试模块简单的将它的输出结果剪切并粘贴到文档字符串中
00:14
通过用户提供的例子,它强化了文档
00:21
允许 doctest 模块确认代码的结果是否与文档一致
00:12
def average(values) 函数定义
00:49
def average(values) 加载函数没问题
00:10
import doctest 成功导入该模块
00:09
dir(doctest) 查看有哪些属性和方法
00:42
自动验证嵌入测试
00:11
doctest.testmod() # 自动验证嵌入测试
00:14
unittest 是一个独立的模块
00:28
unittest模块不像 doctest模块那么容易使用
00:10
不过它可以在一个独立的文件里提供一个更全面的测试集
00:22
import unittest
00:16
class TestStatisticalFunctions(unittest.TestCase)
00:18
def test_average(self) 定义类方法
00:26
加载 unittest 模块和自定义类到内存中
00:19
unittest.main() 测试完成。没有问题
00:25
Python 量化编程基础 2023 告一段落。新的系列就在路上
00:50
新的系列马上开始。主要用 PDF 文件做介绍
00:48
先通过 PDF 讲知识,然后在 Spyder 中展示代码做测试
00:37
Python 数据科学 速查表
00:39
Python 数据科学 - 速查表
00:27
Numpy 基础
00:20
为什么会有 numpy 这个扩展模块
00:48
Numpy 是 Python 数据科学计算的核心库
00:21
提供了高性能的多维数组对象及处
00:30
Numpy 是 Python 数据科学计算模块的基础模块
00:17
import numpy as np
00:17
numpy 注意首字母要小写
00:22
numpy 项目的标志
00:17
NumPy 数组
00:15
1维数组
00:22
2维数组
00:34
numpy 中处理二维数组非常方便
00:39
2维数组对应于数学中的矩阵结构
00:15
3维数组
00:37
3维数组在 numpy 中有很多方法处理
00:12
3维数组进入空间立体结构更复杂的多
00:21
创建数组
00:20
a = np.array([1,2,3])
00:23
b = np.array([(1.5,2,3), (4,5,6)], dtype = float)
00:40
c = np.array([[(1.5,2,3), (4,5,6)], [(3,2,1), (4,5,6)]],dtype = float)
00:54
初始化占位符
00:23
np.zeros((3,4))
00:19
创建值为1的数组
00:27
d = np.arange(10,25,5)
00:17
d = np.arange(10,25,5) 同Python 中 range() 函数做对比
00:39
np.linspace(0,2,9)
00:20
np.linspace(0,2,9) 一次生成一组数据
00:27
e = np.full((2,2),7)
00:12
常数数字的常数是第二个参数
00:19
f = np.eye(2)
00:18
f = np.eye(10) 10乘以10的矩阵
00:17
np.random.random((2,2))
00:36
numpy 也有随机数生成模块,可以方便的生成随机数数组
00:25
np.empty((3,2))
00:19
np.empty((3,2)) 每个元素都是 1 。并不是 0 或者 空数据
00:20
输入-输出
00:33
输入和输出操作是最重要的数据分析操作之一
01:03
保存与载入磁盘上的文件
00:20
np.save('my_array', a)
00:23
np.savez('array.npz', a, b)
00:22
np.load('my_array.npy')
00:17
保存与载入文本文件
00:22
np.loadtxt('myfile.txt')
00:15
np.genfromtxt('my_file.csv', delimiter=',')
00:22
np.genfromtxt('my_file.csv', delimiter=',') 数据用逗号分隔符分开
00:27
my_file.csv 默认用 excel 打开文件
00:12
np.savetxt('myarray.txt', a, delimiter=' ')
00:21
数据类型
00:21
numpy 中的数据类型与 Python 基础类型不完全一致
00:26
np.int64
00:10
np.float32
00:11
np.complex
00:10
np.bool
00:12
np.object
00:15
np.string_
00:20
np.unicode
00:13
numpy有多种自定义的数据类型
00:14
numpy 数据类型是基础数据类型的延伸
00:18
可以在生成数组时设置他们的类型
00:26
数组信息
00:35
a.shape
00:12
len(a)
00:08
b.ndim
00:08
e.size
00:07
b.dtype
00:09
b.dtype.name
00:19
b.astype(int)
00:21
对数组中每一个数据进行转换
00:27
numpy 调用帮助
00:26
np.info(np.ndarray.dtype)
00:17
数组计算
00:24
算数运算
00:15
g = a - b
00:22
a-b 正常运行没有问题
00:19
np.subtract(a,b) 做减法有可行
00:10
b + a
00:10
np.add(b,a)
00:12
a 斜杠 b,进行除法运算
00:12
np.divide(a,b)
00:11
a 星号 b,乘法运算
00:09
np.multiply(a,b)
00:17
np.exp(b) 幂运算没问题
00:11
np.sqrt(b)
00:08
np.sin(a)
00:09
np.cos(b)
00:09
np.log(a)
00:10
e.dot(f)
00:24
numpy 对四则运算的符号做了运算符重载
00:23
数组不但可以做算数运算也可以做比较运算
00:20
array 数据可以使用 == 做比较运算
00:14
array 数据也可以使用 小于号 做比较运算
00:11
np.array_equal(a, b)
00:09
比较运算符也可以进行重载
00:16
聚合函数
00:21
数组array对象的方法
00:19
a.sum()
00:20
a.min()
00:14
b.max(axis=0)
00:21
b.cumsum(axis=1)
00:18
a.mean()
00:15
b.median()
00:12
a.corrcoef()
00:19
np.std(b)
00:13
布林线指标中就使用了标准差概念
00:31
数组复制
00:19
h = a.view()
00:12
np.copy(a)
00:10
h = a.copy()
00:09
数组排序
00:11
a.sort()
00:13
c.sort(axis=0)
00:23
子集、切片、 索引
00:11
a[2]
00:23
b[1,2]
00:19
索引从零开始
00:22
什么是切片
00:15
a[0 2]
00:25
b[0 2,1]第1-2行,第2列
00:19
b[ 1]
00:24
c[1,...]
00:21
a[ -1] 反转数组a
00:14
条件索引
00:24
a[a 小于 2]
00:10
花式索引
00:16
b[[1, 0, 1, 0],[0, 1, 2, 0]]
00:30
b[[1, 0, 1, 0],[0, 1, 2, 0]] 两个列表分别提供横纵坐标
00:17
b[[1, 0, 1, 0]][ ,[0,1,2,0]]选择矩阵的行列子集
00:21
数组操作
00:30
转置数组
00:16
i = np.transpose(b)
00:18
i.T 对数组进行转置操作
00:17
改变数组形状
00:22
b.ravel()
00:10
g.reshape(3,-2)
00:09
改变数组的行列数据但内容不变
00:21
添加或删除值
00:14
h.resize((2,6))
00:13
np.append(h,g)
00:21
np.insert(a, 1, 5)
00:15
np.delete(a,[1])
00:11
合并数组
00:09
np.concatenate((a,d),axis=0)
00:18
np.vstack((a,b))
00:15
np.r_[e,f]
00:13
np.hstack((e,f))
00:16
np.column_stack((a,d))
00:21
np.c_[a,d]
00:11
分割数组
00:10
np.hsplit(a,3)
00:16
np.vsplit(c,2)
00:12
数组操作比较复杂但功能强大
00:19
numpy 速查表基本介绍完成
00:19
快速了解某个重要 Python 扩展库的核心功能
00:53
Pandas 基础
00:29
Pandas 是什么
00:17
Pandas 是基于 Numpy 创建的 Python 库
00:29
为 Python 提供了易于使用的数据结构和数据分析工具
00:30
数据框是更复杂而实用的结构
00:47
使用以下语句导入 Pandas 库
00:16
import pandas as pd
00:28
Pandas 数据结构
00:23
Pandas 有两种数据结构
00:10
Series - 序列
00:15
序列结构示意图
00:18
pd.Series() 生成序列结构
00:15
pd.Series() 生成序列案例分析
00:25
序列类型与字典类型有些相似
00:23
DataFrame - 数据框
00:18
存储不同类型数据的二维数组
00:16
数据框结构的实例分析
00:27
两个步骤生成数据框数据
00:16
首先生成列名称与单列数据的字典数据
00:48
第二步使用 pd.DataFrame() 生成数据框
00:25
pd.DataFrame()使用总结
00:42
pd.Series()应该是一个构造方法
00:13
pd.DataFrame()也应该是生成数据框对象的构造方法
00:14
输入 - 输出 pandas 数据
00:27
文件类型丰富。所以输入-输出也很复杂
00:18
DF文件数据很多,读取写入文件要容易很多
00:19
读取-写入CSV
00:13
pd.read_csv('file.csv', header=None, nrows=5)
00:16
pd.read_csv('file.csv', header=None, nrows=5) 参数分析
00:19
df.to_csv('myDataFrame.csv')
00:29
读取与写入csv文件在不同对象中
00:17
读取 写入Excel
00:16
Excel 是重要的数据源文件
00:18
pd.read_excel('file.xlsx')
00:12
pd.read_excel() 模块中的函数
00:16
pd.to_excel()写入文件
00:25
pd.to_excel() 函数调用有可能有错
00:35
读取内含多个表的Excel
00:14
xlsx = pd.ExcelFile('file.xls')
00:20
pd.ExcelFile('file.xls') 读取Excel文件
00:14
df = pd.read_excel(xlsx, 'Sheet1')
00:27
读取内含多个表的Excel。需要分成两个步骤执行
00:13
读取和写入 SQL 查询及数据库表
00:13
数据库表是重要的数据来源
00:27
SQL 语言是重要工具
00:18
Python 可以直接调用 SQL 命令操作数据库
00:25
方便 DBA 快速调用 SQL 命令完成工作
00:31
from sqlalchemy import create_engine
00:26
create_engine 数据库访问接口
00:35
生成数据库引擎,连接数据库
00:14
pd.read_sql('SELECT FROM my_table;', engine)
00:37
pd.read_sql_table('my_table', engine)
00:17
pd.read_sql_query('SELECT FROM my_table;', engine)
00:17
read_sql()是 read_sql_table() 与 read_sql_query()的便捷打包器
00:17
SELECT FROM my_table;
00:29
read_sql() 更简单更方便
00:15
pd.to_sql('myDf', engine)
00:28
调用帮助
00:16
help(pd.Series.loc)
00:20
取值
00:24
s['b']
00:12
s['b'] 分析含义和数据结构
00:21
df[1 冒号]
00:25
df[1 冒号] 从0开始索引数据
00:18
选取、布尔索引及设置值
00:23
选取、布尔索引及设置值的主要操作
00:30
按位置 访问数据
00:10
df.iloc[[0],[0]]
00:16
df.iloc[[0],[0]] 零行零列数据
00:16
df.iat([0],[0])
00:13
df.iat([0],[0]) 对应零行零列数据
00:15
注意数据框类型是按照列表的方式传递数据
00:25
按照位置访问数据,方法名中有 i 字符
00:13
按标签 访问数据
00:24
df.loc[[0], ['Country']]
00:16
df.loc[[0], ['Country']] 分析说明
00:18
df.at([0], ['Country'])
00:12
df.at([0], ['Country']) 分析说明
00:15
按行与列的名称选择某值
00:16
与之前方法的区别与联系
00:19
按标签-位置,同时做
00:17
df.ix[2]
00:35
df.ix[2] 代码解析
00:16
选择某行
00:08
df.ix[冒号,'Capital']
00:08
df.ix[冒号,'Capital']指定列,但是不指定行
00:17
df.ix[1,'Capital' ]
00:07
df.ix[1,'Capital' ] 代码解析
00:13
布尔索引
00:14
s[~(s 大于 1)]
00:16
s[~(s 大于 1)] 代码解析
00:19
序列 S 中没有大于1的值
00:13
s[(s 小于 -1) 或 (s 大于 2)]
00:09
s[(s 小于 -1) 或 (s 大于 2)] 代码解析
00:11
序列 S 中小于-1或大于2的值
00:17
df[df[]]
00:20
df[df[]] 代码解析
00:12
使用筛选器调整数据框
00:16
设置值
00:12
s['a'] = 6
00:10
对指定序列数据做修改
00:14
将序列 S 中索引为 a 的值设为6
00:07
前几集的内容都是对数据进行访问、修改等操作
00:22
df 数据访问方式非常灵活
00:23
根据位置信息进行访问
00:14
按照标签访问数据
00:26
按照索引或者位置来访问数据也没问题
00:22
删除数据
00:22
s.drop(['a', 'c'])
00:16
s.drop(['a', 'c']) 代码分析
00:22
按索引删除序列的值 (axis=0)
00:09
df.drop('Country', axis=1)
00:10
df.drop('Country', axis=1) 代码分析
00:18
按列名删除数据框的列(axis=1)
00:08
可以删除某几个序列数据,也可以直接删除一列
00:23
排序和排名
00:20
股票算法首要的任务就是进行过滤,筛选满足条件的股票
00:18
过滤得到满足条件的股票之后,下一步就是进行排序操作
00:18
df.sort_index()
00:14
df.sort_index() 按照索引进行排序
00:25
按索引排序
00:09
df.sort_values(by='Country')
00:09
by='Country'
00:17
按某列的值排序
00:14
df.rank()
00:06
df.rank() 根据 df 排名做排序
00:08
数据框排名
00:13
查询序列与数据框的信息
00:17
基本信息
00:13
df.shape
00:07
df.shape 只是属性不是函数
00:13
df.shape 返回数据框行列信息
00:14
df.index
00:10
df.index 只是一个属性。用于获取索引信息
00:08
df.columns
00:07
df.columns 获取列名信息
00:09
df.info()
00:07
获取数据框基本信息
00:18
df.count()
00:07
非Na值的数量
00:17
汇总
00:14
df.sum()
00:08
df.cumsum()
00:06
df.min() df.max()
00:14
df.max() 取最大值
00:11
df.idxmin()
00:10
df.idxmax() 索引的最大值
00:08
df.describe()
00:22
df.mean()
00:11
df.median()
00:11
应用函数
00:32
f = lambda x 冒号 x 星号2
00:14
df.apply(f)
00:19
df 是已经定义好的数据框
00:15
应用匿名函数lambda
00:12
df.applymap(f)
00:09
对每个单元格应用函数
00:13
数据对齐
00:12
数据对齐有两种方式
00:15
内部数据对齐
00:08
如有不一致的索引,则使用NA值
00:09
s3 = pd.Series([7, -2, 3], index=['a', 'c', 'd'])
00:21
s + s3
00:16
s + s3 有 NaN 数据占位置
00:25
使用 Fill 方法运算
00:11
还可以使用 Fill 方法进行内部对齐运算
00:22
s.add(s3, fill_value=0)
00:23
s.add(s3, fill_value=0) 结果分析。完全正确
00:38
s.sub(s3, fill_value=2)
00:28
s.sub(s3, fill_value=2) 结果分析
00:24
s.div(s3, fill_value=4)
00:12
s.div(s3, fill_value=4) 结果分析
00:15
s.mul(s3, fill_value=3)
00:13
s.mul(s3, fill_value=3) 计算结果分析
00:09
除了Python基础,还要学习交易平台
00:26
介绍一些基础的原始算法,看看他们的表现
00:31
小市值-原始模型-2010年以来表现情况
00:15
2023-08-11 测试了这个模型
00:19
2010-01-01 - 2023-08-10,历史数据回测时间范围
00:25
11分15秒,14年半历史数据回测的时间
00:17
运行频率是 每天 的日线数据做测试
00:14
十四年半时间,理论收益率高达 46 倍
00:16
基准收益率和这个概念的意义
00:25
算法回撤非常大,接近腰斩是什么原因呢?
00:13
回测状态是完成的
00:17
正在回测时看不到状态反馈信息,没有 完成 结果
00:25
每条记录对应一次回测的整体结果
00:28
点击之后看到回测后的结果界面
00:28
使用1000万资金做回测
00:35
整体净值曲线图
00:24
交易次数,胜率和盈亏比
00:31
最大回撤出现的时间段
00:21
最大回撤出现的原因
00:34
2015年依然有盈利,并且最后3个月重新创新高
00:23
分析小市值原始模型代码
00:24
设置回测时间和金额
00:31
设置行情数据分析的时间尺度
00:13
我们设置 Python 3 为编程语言
00:08
点击 回测列表,查看所有回测记录
00:34
点击 编辑策略 进入策略代码的编辑界面
00:11
免费的回测时长和回测规则介绍
00:27
小市值原始模型,总行数还不到90行
00:12
导入函数库
00:17
from jqdata import 星
00:13
直接导入函数名的好处
00:31
初始化函数,设定基准等等
00:16
def initialize(context)
00:12
设定持股数量
00:15
g.stocknum = 10
00:10
g.stocknum 全局变量
00:14
设定买入list
00:18
g.buylist = []
00:10
g.buylist = [] 建立空列表,准备存放股票代码
00:11
设定沪深300作为基准
00:25
set_benchmark('000300.XSHG')
00:10
set_benchmark('000300.XSHG') 沪深300指数为标准
00:33
开启动态复权模式(真实价格)
00:13
set_option('use_real_price', True)
00:18
除权、除息后股价会发生变化。我们要使用当时的股价数据做交易
00:45
成交量不大于0.1
00:13
set_option('order_volume_ratio', 0.1)
00:17
set_option('order_volume_ratio', 0.1) 使用实际成交量的一成做历史数据回测
00:51
输出内容到日志 log.info()
00:11
log.info('初始函数开始运行且全局只运行一次')
00:17
log.info('初始函数开始运行且全局只运行一次') 只会在日志中留下一个记录
00:28
过滤掉order系列API产生的比error级别低的log
00:11
log.set_level('order', 'error')
00:14
log.set_level('order', 'error') 过滤一般警告信息,除非出现错误,否则不会记录
00:59
设置滑点
00:08
set_slippage(FixedSlippage(0.02))
00:15
set_slippage(FixedSlippage(0.02)) 设置滑点为 2 分钱
00:15
提交到服务器的单子会按照指定价格成交。不满足价格条件一般会挂单
00:44
看年度收益了解每年的基本收益情况
00:21
年度收益图的基本结构
00:38
2010年的年度表现分析
00:32
2011年要亏损十几个百分点
00:21
2011年亏损的原因是什么
00:30
2012年盈利超过25%,是个有利的年份
00:18
2013年对小盘股非常有利
00:19
2014年非常有利。下半年遇到了大牛市行情
00:14
2015年是大牛市行情。中途回撤巨大,但最后一个季度又拉回来
00:23
2016年是盈利继续增长的年份
00:21
2017年是亏损的年份
00:13
2023年还是比较不错的年份
00:13
2017年大盘股表现好,小盘股表现一般
00:25
2017年损失是 -25.77%。对小盘股模型很不利
00:11
2018年亏损是 -24.92%
00:10
贸易战使小盘股模型表现也不利
00:24
2019年小盘股模型就很有利了
00:14
2020年对小盘股模型也不利
00:12
2017-2018年累计损失是 40% 左右
00:23
2021年行情还比较配合
00:16
2022年的行情也还比较不错
00:11
最近2.5年大盘股模型不太有利,小盘股模型很不错
00:19
最近2.5年整理收益率还不错
00:15
并不是每年都能大赚特赚
00:27
必须做好连续两年亏损的心理准备
00:12
在行情有利时大赚,行情不利时做好防御
00:22
run_daily(stoploss, '10冒号00')
00:17
每天上午 10 点运行,看是否有股票需要止损出场
00:19
股票相关设定
00:10
股票类每笔交易时的手续费是:买入时佣金万分之三,卖出时佣金万分之三加千分之一印花税, 每笔交易佣金最低扣5块钱
00:19
set_order_cost(OrderCost(close_tax=0.001, open_commission=0.0003, close_commi
00:18
set_order_cost(OrderCost(close_tax=0.001, open_commission=0.0003
00:25
运行函数(reference_security为运行时间的参考标的;传入的标的只做种类区分,因此传入'000300.XSHG'或'510300.XSHG'
00:21
开盘前运行
00:08
每周第一个交易日,九点半运行股票过滤函数
00:19
get_index_stocks('000001.XSHG') 获取指数成分股列表
00:30
run_weekly(filter_stocks,1,'09冒号30')
00:10
每周第一个交易日十点运行开市相关函数
00:23
run_weekly(market_open, 1,'10冒号00')
00:08
初始化函数中详细设定了各种所需要的环境参数
00:51
运行筛股函数
00:10
def filter_stocks(context)
00:16
def filter_stocks(context) 依靠context传递相关参数
00:21
输出运行时间
00:10
log.info(str('函数运行时间(filter_stocks)冒号'+str(context.current_dt.time())))
00:27
写入的是回测过程中,历史行情的时间
00:52
curr_data = get_current_data()
00:11
获取上证指数和深证综指的成份股
00:13
过滤股票之前先在日志中记录当时的历史时间
00:20
curr_data = get_current_data() 获取当前环境数据
00:21
获取综合指数成分股的股票名称数据
00:09
scu = get_index_stocks('000001.XSHG') + get_index_stocks('399106.XSHE')
00:23
scu = get_index_stocks('000001.XSHG') + get_index_stocks('399106.XSHE') 两个股指对
00:16
当时的股票指数对应成分股列表
00:26
scu = get_index_stocks('399102.XSHE')
00:23
过滤 ST 及含有退市标签股票
00:19
stock for stock in scu if not
00:23
curr_data[stock].day_open == curr_data[stock].high_limit
00:30
curr_data[stock].day_open == curr_data[stock].low_limit
00:15
开盘涨跌停就被过滤了。但十点钟交易时或许打开涨跌停板
00:28
curr_data[stock].paused
00:12
('ST' in curr_data[stock].name)
00:12
('星号' in curr_data[stock].name)
00:12
('退' in curr_data[stock].name)
00:11
过滤掉所有异常股票
00:36
获取市值最小的股票列表
00:26
q=query(valuation.code,valuation.market_cap).filter(valuation.code.in_(scu)).
00:31
q=query(valuation.code,valuation.market_cap))
00:59
df = get_fundamentals(q,date = context.previous_date)
00:27
df = get_fundamentals(q,date = context.previous_date) 基础
00:23
stocklist = list(df['code'])
00:09
stocklist = list(df['code']) 列表
00:32
生成买入列表
00:06
g.buylist = stocklist
00:09
g.buylist = stocklist 列表
00:26
def filter_stocks(context) 获取过滤后满足条件的股票代码
00:59
止损函数用于判断是否满足止损条件。如果满足就止损
00:14
def stoploss(context)
00:13
for stock in context.portfolio.positions
00:13
for stock in context.portfolio.positions 遍历资产组合中的每只股票做操作
00:12
cost = context.portfolio.positions[stock].avg_cost
00:16
cost = context.portfolio.positions[stock].avg_cost 持股均价赋值给变量
00:17
price = context.portfolio.positions[stock].price
00:14
price = context.portfolio.positions[stock].price 当前股价赋值给变量
00:17
ret = price 除号 cost-1
00:10
计算当前这支股票的收益率
00:19
if ret 小于 -0.2
00:11
如果收益率小于 -0.2 则进行下面的操作
00:17
order_target(stock,0)
00:07
order_target(stock,0) 清空这支股票
00:19
order_target(stock,0) 清空
00:22
g.stocks = [] 清空已经平仓的股票信息
00:09
log.info('触发止损')
00:08
将 触发止损 这句话写入日志
00:09
止损函数用于判断是否达到止损条件。如果满足则清空对应股票并删除相关信息
00:30
开盘时运行函数
00:07
def market_open(context)
00:06
输出运行时间
00:06
log.info(str('函数运行时间(market_open)冒号'+str(context.current_dt.time())))
00:07
在日志中写入这个函数调用的时间
00:21
log.info(str('函数运行时间(market_open)冒号'+str(context.current_dt.time()))) 历史时间,不是
00:17
调仓 - 重要操作
00:08
if(len(g.buylist)==0)
00:11
g.buylist 判断是否为 0
00:09
g.buylist 为 0,表示没有需要买入的股票。直接返回
00:08
rebalance(context,g.buylist)
00:11
rebalance(context,g.buylist) 进行平仓和开仓操作
00:12
调仓rebalance函数
00:06
def rebalance(context,holding_list) 定义
00:10
def rebalance(context,holding_list) 函数参数介绍
00:13
目前有 120 行代码了
00:17
每只股票购买金额
00:08
every_stock = context.portfolio.portfolio_value 除号 len(holding_list)
00:10
计算每只股票购买的金额数量
00:28
空仓就全部买入,等额资金
00:16
初始状态只有现金,没有股票
00:22
if len(list(context.portfolio.positions.keys())) == 0
00:19
判断持仓股票数量是否为零
00:27
for stock_to_buy in holding_list
00:08
对待购买股票列表做遍历操作
00:26
order_target_value(stock_to_buy, every_stock)
00:08
order_target_value(stock_to_buy, every_stock) 照着额度买股票
00:27
如果不是空仓先卖出持有但是不在购买名单中的股票
00:08
不在清单中的股票要先清仓
00:19
for stock_to_sell in list(context.portfolio.positions.keys())
00:11
对于持仓进行遍历分析
00:24
if stock_to_sell not in holding_list
00:15
判断持仓是否在新买入列表中
00:24
order_target_value(stock_to_sell, 0)
00:10
完全清空不在列表中的股票
00:10
为holding_list里的每支股票分配等额资金
00:10
for i in holding_list
00:08
针对每只待买入列表中的股票做操作
00:10
order_target_value(i, every_stock)
00:08
针对每只待买入股票,买够相关的金额
00:12
再平衡函数用于建仓或者调仓股票
00:35
前期介绍该模型的全部代码
00:31
设置模型的回测时间段
00:18
点击 运行回测 开始回测数据
00:14
系统初始化然后开始回测
00:26
2010年行情总结
00:10
2011年行情不太有利
00:27
2012年行情还不错
00:24
2013年小市值模型表现好
00:26
2014年上半年行情不错。下半年遇到牛市起点
00:29
2015年上半年继续大牛市,中途大回撤,年底重回高点
00:32
2016年开年熔断股灾,之后模型依然强势
00:31
2017年小市值模型不利
00:39
2018年贸易战,主要模型都不利
00:38
2019年行情开始修复
00:41
2020年行情还是不利。大盘股涨的好
00:45
2021年小盘股模型比较有利
00:39
2022年小盘股模型扛住下跌继续有利
00:47
2023年小盘股模型表现不错。特别是7月以来
00:38
模型运行结束后系统自动汇总数据做初步统计
00:24
客服
顶部
赛事库 课堂 2021拜年纪