这篇文章主要介绍了Python函数式编程指南(一):函数式编程概述,本文讲解了什么是函数式编程概述、什么是函数式编程、为什么使用函数式编程、如何辨认函数式风格等核心知识,需要的朋友可以参考下1pareTo(o2))相信从这个小小的例子你也能感受到强大的生产效率:)封装控制结构的内置模板函数为了避开边界效应,函数式风格尽量避免使用变量,而仅仅为了控制流程而定义的循环变量和流程中产生的临时变量无疑是最需要避免的。假如我们需要对刚才的数集进行过滤得到所有的正数,使用指令式风格的代码应该像是这样:代码如下:lst2 = list()for i in range(len(lst)): #模拟经典for循环if lst[i] 0:lst2.append(lst[i])这段代码把从创建新列表、循环、取出元素、判断、添加至新列表的整个流程完整的展示了出来,俨然把解释器当成了需要手把手指导的傻瓜。然而,“过滤”这个动作是很常见的,为什么解释器不能掌握过滤的流程,而我们只需要告诉它过滤规则呢?在Python里,过滤由一个名为filter的内置函数实现。有了这个函数,解释器就学会了如何“过滤”,而我们只需要把规则告诉它:代码如下:lst2 = filter(lambda n: n 0, lst)这个函数带来的好处不仅仅是少写了几行代码这么简单。封装控制结构后,代码中就只需要描述功能而不是做法,这样的代码更清晰,更可读。因为避开了控制结构的干扰,第二段代码显然能让你更容易了解它的意图。另外,因为避开了索引,使得代码中不太可能触发下标越界这种异常,除非你手动制造一个。函数式编程语言通常封装了数个类似“过滤”这样的常见动作作为模板函数。唯一的缺点是这些函数需要少量的学习成本,但这绝对不能掩盖使用它们带来的好处。闭包(closure)闭包是绑定了外部作用域的变量(但不是全局变量)的函数。大部分情况下外部作用域指的是外部函数。闭包包含了自身函数体和所需外部函数中的“变量名的引用”。引用变量名意味着绑定的是变量名,而不是变量实际指向的对象;如果给变量重新赋值,闭包中能访问到的将是新的值。闭包使函数更加灵活和强大。即使程序运行至离开外部函数,如果闭包仍然可见,则被绑定的变量仍然有效;每次运行至外部函数,都会重新创建闭包,绑定的变量是不同的,不需要担心在旧的闭包中绑定的变量会被新的值覆盖。回到刚才过滤数集的例子。假设过滤条件中的 0 这个边界值不再是固定的,而是由用户控制。如果没有闭包,那么代码必须修改为:代码如下:class greater_than_helper:def __init__(self, minval):self.minval = minvaldef is_greater_than(self, val):return val self.minvaldef my_filter(lst, minval):helper = greater_than_helper(minval)return filter(helper.is_greater_than, lst)请注意我们现在已经为过滤功能编写了一个函数my_filter。如你所见,我们需要在别的地方(此例中是类greater_than_helper)持有另一个操作数minval。如果支持闭包,因为闭包可以直接使用外部作用域的变量,我们就不再需要greater_than_helper了:代码如下:def my_filter(lst, minval):return filter(lambda n: n minval, lst)可见,闭包在不影响可读性的同时也省下了不少代码量。函数式编程语言都提供了对闭包的不同程度的支持。在Python 2.x中,闭包无法修改绑定变量的值,所有修改绑定变量的行为都被看成新建了一个同名的局部变量并将绑定变量隐藏。Python 3.x中新加入了一个关键字 nonlocal 以支持修改绑定变量。但不管支持程度如何,你始终可以访问(读取)绑定变量。内置的不可变数据结构为了避开边界效应,不可变的数据结构是函数式编程中不可或缺的部分。不可变的数据结构保证数据的一致性,极大地降低了排查问题的难度。例如,Python中的元组(tuple)就是不可变的,所有对元组的操作都不能改变元组的内容,所有试图修改元组内容的操作都会产生一个异常。函数式编程语言一般会提供数据结构的两种版本(可变和不可变),并推荐使用不可变的版本。递归递归是另一种取代循环的方法。递归其实是函数式编程很常见的形式,经常可以在一些算法中见到。但之所以放到最后,是因为实际上我们一般很少用到递归。如果一个递归无法被编译器或解释器优化,很容易就会产生栈溢出;另一方面复杂的递归往往让人感觉迷惑,不如循环清晰,所以众多最佳实践均指出使用循环而非递归。这一系列短文中都不会关注递归的使用。第一节完
上高网站建设公司创新互联,上高网站设计制作,有大型网站制作公司丰富经验。已为上高超过千家提供企业网站建设服务。企业网站搭建\成都外贸网站建设要多少钱,请找那个售后服务好的上高做网站的公司定做!
Lambda 函数
Python 函数一般使用 def a_function_name() 样式来定义,但是对于 lambda 函数来说,我们其实根本没为它命名。这是因为 lambda 函数的功能是执行某种简单的表达式或运算,而无需完全定义函数。
Map 函数
Map() 是一种内置的 Python 函数,它可以将函数应用于各种数据结构中的元素,如列表或字典。对于这种运算来说,这是一种非常干净而且可读的执行方式。
Filter 函数
filter 内置函数与 map 函数非常相似,它也将函数应用于序列结构(列表、元组、字典)。二者的关键区别在于 filter() 将只返回应用函数返回 True 的元素。
Itertools 模块
Python 的 Itertools 模块是处理迭代器的工具集合。迭代器是一种可以在 for 循环语句(包括列表、元组和字典)中使用的数据类型。
使用 Itertools 模块中的函数让你可以执行很多迭代器操作,这些操作通常需要多行函数和复杂的列表理解。
Generator 函数
其实,Generator函数是一个类似于迭代器的函数,就是它也可以用在 for 循环语句中。这大大简化了你的代码,而且相比简单的 for 循环,它节省了很多内存。
关于Python的5种高级用法,青藤小编就和您分享到这里了。如果您对python编程有浓厚的兴趣,希望这篇文章可以为您提供帮助。如果您还想了解更多关于python编程的技巧及素材等内容,可以点击本站的其他文章进行学习。
作者看着网上各种数据分析的知识泛滥, 但是没有什么体系,初学者不知道学哪些, 不知道学多少, 不知道学多深, 单纯一个python语言, 数据分析会用到那种程度, 不可能说像开发那样去学, numpy如果不是做算法工程师用到的知识并不多, pandas知识杂乱无章, 哪些才是最常用的功能等等, 作者不忍众生皆苦, 决定写一套python数据分析的全套教程, 目前已完成一部分课件的制作。需要说明的是, 作为一名数据分析师, 你应该先会一点Excel和SQL知识,相关的内容, 网上很多。但是, 即便你一点Excel和SQL都不会也不会影响这部分的学习 !目前作者整理的大纲如下:
第一章 python编程基础
1.1 python语言概述 1.2 数据科学神器--Anaconda介绍与安装 1.3 标准输入输出 1.4 变量定义与赋值 1.5 数据类型 1.6 流程控制语句 1.7 函数
1.8 面向对象编程 第二章 python数据清洗之numpy 2.1 核心ndarray对象的创建 2.2 ndarray对象常用的属性和方法 2.3 ndarray对象的索引和切片 2.4 ndarray对象的分割与合并 2.5 ndarray对象的广播(Broadcast) 2.6 numpy中的算术运算函数 2.7 numpy中的统计函数 2.8 numpy中的排序 搜索 计数 去重函数 2.9 numpy中的字符串函数 2.10 numpy中可能会用到的线性代数模块(后期机器学习会用到一点)
第三章 数据清洗神器pandas
3.1 pandas核心对象之Series对象的创建 常用属性和方法 3.2 pandas核心对象之DataFrame对象的创建 常用属性和方法 3.3 DataFrame对象的列操作和行操作 3.4 DataFrame对象的索引和切片 3.5 DataFrame对象的布尔索引 3.6 数据的读入与导出 3.7 groupby分组运算 3.8 数据合并与数据透视
第四章 数据可视化matplotlib seaborn pyecharts
4.1 包括常用图形的绘制,略
第五章 实战案列
5.1 拉勾网数据分析相关职位分析 5.2 boss直聘数据分析相关职位分析 5.3 珍爱网女性用户数据分析
第六章 机器学习
机器学习部分, 简单的算法会讲手写, 难的就用scikit-learn实现, 可能有小伙伴说, 这是调包侠干的, 小哥哥!小姐姐!哪有那么多公司, 那么多人自己干写算法的, 有几个人敢说他写的算法比scikit-learn写得好? 再说了, 你是数据分析师, 这些是你的工具, 解决问题的!不是一天到晚拉格朗日对偶性!先来个机器学习介绍, 然后如下:
6.1 K近邻算法 6.2 Kmeans算法 6.3 决策树 阶段案列:决策树案列(保险行业) 6.4 线性回归 岭回归 Lasso回归 6.5 逻辑回归 6.6 朴素贝叶斯 阶段案列:推荐系统(电商玩具) 6.7 随机森林 6.8 Adaboost 6.9 梯度提升树GBDT 6.10 极端梯度提升树Xgboost 6.11 支持向量机SVM 6.12 神经网络 阶段案例:Xgboost案例
------------------------------本节内容-----------------------------------------
python语言概述
在说python之前, 我们还是先来看看计算机软硬件的发展历史。
1 计算机硬件的发展历史
第一代计算机-电子管计算机(1946-1957)
无论如何,一项技术的突破必然伴随着其他行业的突破,简而言之,电子计算机的出现,前提必须有电子技术的进步,否则一切都是空谈!下面是我列举出计算机硬件的发展过程中, 一些比较重要的事件。
1906年, 美国的Lee De Forest 发明了电子管。在这之前造出数字电子计算机是不可能的。这为电子计算机的发 展奠定了基础。
1924年2月, 一个具有划时代意义的公司成立,IBM。
1935年, IBM推出IBM 601机。 这是一台能在一秒钟算出乘法的穿孔卡片计算机。这台机器无论在自然科学还是在商业意义上都具有重要的地位。大约造了1500台。
1937年, 英国剑桥大学的Alan M. Turing (1912-1954)出版了他的论文 ,并提出了被后人称之为"图灵机"的数学模型。
1937年, 美国贝尔试验室的George Stibitz展示了用继电器表示二进制的装置。尽管仅仅是个展示品,但却是世界上第一台二进制电子计算机。
1941年, Atanasoff和学生Berry完成了能解线性代数方程的计算机,取名叫"ABC"(Atanasoff-Berry Computer),用电容作存储器,用穿孔卡片作辅助存储器,那些孔实际上是"烧"上的。 时钟频率是60HZ,完成一次加法运算用时一秒。这就是ABC计算机。
1946年, 美国宾夕法尼亚大学,第一台通用电子计算机ENIAC (Electronic Numerical Integrator 和 Computer)诞生, 总工程师埃克特在当时年仅25岁。
这时的计算机的基本线路是采用电子管结构,程序从人工手编的 机器指令程序(0 1),过渡到符号语言(汇编),电子管计算机是计算工具革命性发展的开始,它所采用的进位制与程序存贮等基本技术思想,奠定了现代电子计算机技术基础。以冯·诺依曼为代表。
第二代计算机——晶体管计算机(时间1957~1964)
电子管时代的计算机尽管已经步入了现代计算机的范畴,但其体积之大、能耗之高、故障之多、价格之贵大大制约了它的普及应用。直到晶体管被发明出来,电子计算机才找到了腾飞的起点,一发而不可收……
20世纪50年代中期,晶体管的出现使计算机生产技术得到了根本性的发展,由晶体管代替电子管作为计算机的基础器件,用 磁芯或磁鼓作存储器,在整体性能上,比第一代计算机有了很大的提高。
第三代计算机——中小规模集成电路计算机(时间1964~1971)
20世纪60年代中期, 计算机发展历程随着半导体工艺的发展,成功制造了集成电路。中小规模集成电路成为计算机的主要部件,主存储器也渐渐过渡到 半导体存储器,使计算机的体积更小,大大降低了计算机计算时的功耗,由于减少了 焊点和 接插件,进一步提高了计算机的可靠性。
第四代计算机——大规模和超大规模集成电路计算机(时间1971~至今)
随着大规模集成电路的成功制作并用于计算机硬件生产过程,计算机的体积进一步缩小,性能进一步提高。集成更高的大容量半导体存储器作为内存储器,发展了并行技术和多机系统,出现了 精简指令集计算机(RISC),软件系统工程化、理论化,程序设计自动化。微型计算机在社会上的应用范围进一步扩大,几乎所有领域都能看到计算机的“身影”。
第五代计算机——泛指具有人工智能的计算机(至今~未来)
目前还没有明确地定义
2 简述计算机软件的发展历史
编程语言的发展
计算机软件系统的发展,也伴随着编程语言的发展。计算机程序设计语言的发展,经历了从机器语言、汇编语言到高级语言的历程。
机器语言:简单点说,机器本身也只认识0和1,电路无非就只有通和断两种状态,对应的二进制就是二进制的1和1。
汇编语言:汇编语言只是把一些特殊的二进制用特殊的符号表示,例如,机器要传送一个数据,假设“传送”这个指令对应的机器码是000101,则人们把000101用一个特殊符号,比如mov来表示,当人们要用这个指令时用mov就行,但是mov的本质还是000101,没有脱离硬件的范围,有可能这个指令不能在其他机器上用。
高级语言:高级语言完全脱离了硬件范畴,所有的语法更贴近人类的自然语言,人们只需要清楚高级语言的语法,写出程序就行了,剩下的交给编译器或者解释器去编译或者解释成机器语言就行了,看,这样就完全脱离了硬件的范畴,大大提高了程序的开发效率。接下来我们就来看看高级语言的发展,高级语言非常多,我们主要看看比较经典的几个。
高级语言的发展
B语言与Unix
20世纪60年代,贝尔实验室的研究员Ken Thompson(肯·汤普森)发明了B语言,并使用B编了个游戏 - Space Travel,他想玩自己这个游戏,所以他背着老板找到了台空闲的机器 - PDP-7,但是这台机器没有操作系统,于是Thompson着手为PDP-7开发操作系统,后来这个OS被命名为 - UNIX。
C语言
1971年,Ken Thompson(肯·汤普森)的同事D.M.Ritchie(DM里奇),也很想玩Space Travel,所以加入了Ken Thompson,合作开发UNIX,他的主要工作是改进Thompson的B语言。最终,在1972年这个新语言被称为C,取BCPL的第二个字母,也是B的下一个字母。
C语言和Unix
1973年,C主体完成。Ken Thompson和D.M.Ritchie迫不及待的开始用C语言完全重写了UNIX。此时编程的乐趣已经使他们完全忘记了那个“Space Travel”,一门心思的投入到了UNIX和C语言的开发中。自此,C语言和UNIX相辅相成的发展至今。
类C语言起源、历史
C++(C plus plus Programming Language) - 1983
还是贝尔实验室的人,Bjarne Stroustrup(本贾尼·斯特劳斯特卢普) 在C语言的基础上推出了C++,它扩充和完善了C语言,特别是在面向对象编程方面。一定程度上克服了C语言编写大型程序时的不足。
Python (Python Programming Language)--1991
1989年圣诞节期间,Guido van Rossum 在阿姆斯特丹,Guido van Rossum为了打发圣诞节的无趣,决心开发一个新的脚本解释程序,做为ABC语言的一种继承。之所以选中Python(大蟒蛇的意思)作为该编程语言的名字,是因为他是一个叫Monty Python的喜剧团体的爱好者。第一个Python的版本发布于1991年。
Java(Java Programming Language) - 1995
Sun公司的Patrick Naughton的工作小组研发了Java语言,主要成员是James Gosling(詹姆斯·高斯林)
C(C Sharp Programming Language) - 2000
Microsoft公司的Anders Hejlsberg(安德斯·海尔斯伯格)发明了C,他也是Delphi语言之父。
当然现在还有一些新语言,比如2009年Google的go语言,以及麻省理工的julia等。
3 为什么是Python
Python有哪些优点
1 语法简单 漂亮:我们可以说Python是简约的语言,非常易于读写。在遇到问题时,我们可以把更多的注意力放在问题本身上,而不用花费太多精力在程序语言、语法上。
2 丰富而免费的库:Python社区创造了各种各样的Python库。在他们的帮助下,你可以管理文档,执行单元测试、数据库、web浏览器、电子邮件、密码学、图形用户界面和更多的东西。所有东西包括在标准库,然而,除了它,还有很多其他的库。
3 开源:Python是免费开源的。这意味着我们不用花钱,就可以共享、复制和交换它,这也帮助Python形成了丰富的社区资源,使其更加完善,技术发展更快。
4 Python既支持面向过程,也支持面向对象编程。在面向过程编程中,程序员复用代码,在面向对象编程中,使用基于数据和函数的对象。尽管面向对象的程序语言通常十分复杂,Python却设法保持简洁。
5 Python兼容众多平台,所以开发者不会遇到使用其他语言时常会遇到的困扰。
Python有哪些作用
Python是什么都能做,但是我们学的是数据分析,我们看看在数据分析领域Python能做什么。
数据采集:以Scrapy 为代表的各类方式的爬虫
数据链接:Python有大量各类数据库的第三方包,方便快速的实现增删改查
数据清洗:Numpy、Pandas,结构化和非结构化的数据清洗及数据规整化的利器
数据分析:Scikit-Learn、Scipy,统计分析,科学计算、建模等
数据可视化:Matplotlib、Seaborn等等大量各类可视化的库
所以说总结, 为什么数据科学选的是python, 最重要就是两个原因:
1 语法简单漂亮
2 大量丰富免费的第三方库
优矿的500万实盘在如火如荼地进行中,我们已经看到有矿友利用经典的机器学习算法和新的Quartz Signal模块对于优矿上现有因子的利用进行探索,但是对于大多数信号/因子研究者来说,寻找新的Alpha依然是其孜孜以求的目标。
如何去寻找新的Alpha因子的灵感成为摆在量化研究者面前无法回避的问题。
我们注意到,Zura Kakushadze 等人最新发表的论文101 Formulaic Alpha(…) 里提到了很多基于价量数据构建的"Alpha"因子,为我们提供了很多新的灵感。
本文将先简单介绍论文中提到的Alpha因子表达式语法以及含义,之后会介绍如何用Quartz Signal便捷地实现这些Alpha,最后会提供2个在论文中出现并且效果不错的Alpha因子供大家参考。
Formulaic Alpha简介
研读过上文提到的论文,我们发现,论文中提到的Formulaic Alpha就是用一个表达式来表示一个Alpha因子:
· 写出的表达式是在每一个调仓日对每一支按照该表达式进行计算
· 例如:1/close; 对universe中每一支,计算1/closePrice,然后此向量被标准化,即除以其数值的总和(所有数值相加的结果为 1)。这将为所有创建了一个基于“权重”的向量,每个权重代表投资组合中投资于该的资金比例
· 其支持的数据有:open(开盘价)/close(收盘价)/high(最高价)/low(最低价)/vwap(日内交易量加权价格)/returns(单日收益率)等等
我们认为这种Formulaic Alpha的表达形式有以下特点:
· 表达简洁,但隐藏了太多细节,用户无法看到具体的调仓信息
· 受限于表达式表达能力的不足,提供了丰富的内置函数,帮助用户完成了cross-sectional信息的处理
内置函数
· 可分为横截面函数和时间序列函数两大类,其中时间序列函数名多为以ts_开头
· 大部分函数命名方式较为直观
· abs(x) log(x)分别表示x的绝对值和x的自然对数
· rank(x)表示某x值在横截面上的升序排名序号,并将排名归一到[0,1]的闭区间
· delay(x,d)表示x值在d天前的值
· delta(x,d)表示x值的最新值减去x值在d天前的值
· correlation(x,y,d) covariance(x,y,d)分别表示x和y在长度为d的时间窗口上的Pearson相关系数和协方差
· ts_min(x,d) ts_max(x,d) ts_argmax(x,d) ts_argmin(x,d) ts_rank(x) sum(x,d) stddev(x,d)等均可以通过函数名称了解其作用
· 更多地函数解释可以参考论文的附录
Quartz Signal模块简介
正如API帮助文档中提到的,Signal模块是优矿为方便因子/信号研究者提供的工具,将用户从与信号研究无关的数据获取、下单逻辑中抽离出来,用户可以将精力集中于按照自己的思路开发新的信号。
使用Signal自定义信号的通用实现过程如下:
def foo(data, dependencies=['PE 39;], max_window=4):
return data['PE 39;].mean()
# in initialize(account)
a = Signal("signal_a", foo)
account.signal_generator = SignalGenerator(a)
# in handle_data(account)
account.signal_result['signal_a']
我们可以将Quartz Signal的使用过程分为四个步骤:
定义实现信号逻辑的函数(在上例中即为foo函数)
在initialize函数中定义Signal,在实例化Signal类时将信号名字和描述函数作为参数传入
在initialize函数中将需要使用的信号注册到account.signal_generator中,可以注册多个信号
在handle_data中通过account.signal_result获取计算好的信号值
我们重点介绍一下用户需要完成的信号描述函数:
信号描述函数实际上是用户在每一个调仓日对于可以获得数据的处理逻辑
信号描述函数名可以按照Python函数的命名规范任意定义,但其参数必须为一个非关键字参数data,两个关键字参数dependencies和max_window
dependencies的参数格式必须为str构成的list,list的元素为该函数中需要使用的因子名称,具体支持因子列表参考帮助文档
max_window的参数格式为int,表示用户希望用到过去max_window天的因子数据
data则是根据dependencies和max_window,Quartz Signal模块帮助用户取到的数据,其格式为一个dict,key为因子名称,value为max_window*universe_length的Pandas DataFrame
信号描述函数的返回值必须为一个长度与data中每一元素列数相同的Pandas Series
如下图所示:
上图描述的就是data的结构,其中data只有一个元素,其key为"PE",value就是上图表格所示的Pandas DataFrame,具体地,其columns为universe的secID,其index为%Y%m%d格式的日期字符串
Quartz Signal v.s. Formulaic Alpha
由上述描述可见,使用Quartz Signal模块可以便捷地实现Formulaic Alpha,同时相比Formulaic Alpha表达式有以下优势:
更加直观:
o用户在预先定义信号描述函数时,就可以明晰地定义自己需要的因子数据和时间窗口
o用户可以在Quartz框架中灵活定义自己的调仓频率和下单逻辑,并可以直观地看到每次调仓的列表
更加灵活:
oFormulaic Alpha限制了表达式的计算结果必须代表相应在投资组合中的权重,而Quartz Signal并没有此限制,用户可以在handle_data中按照自己的想法任意处理信号值
o信号描述函数的data是以Pandas DataFrame的格式传入的,这样用户就可以在函数中同时看到横截面数据和时间序列数据,为用户提供了更多可能
更加强大:信号描述函数的data是以Pandas DataFrame的格式传入的,Pandas丰富的内置函数可以帮助我们完成较复杂Formulaic Alpha表达式才能完成的任务(见最后一个示例)
更多数据:Quartz Signal不仅支持openPrice/closePrice/highPrice/lowPrice/turnoverVol等价量信息,还支持PE、RSI等更丰富的因子
下面我们就用Quartz Signal模块实现了一个论文中提到的Formulaic Alpha:
用Quartz Signal实现一个Formulaic Alpha
以WebSim论文中alpha 53为例,其原始表达式为:
(−1∗delta((((close−low)−(high−close))/(close−low)),9))
化简可得,((close - low) - (high - close)) / (close - low)的9日之前值-当前值
继续化简可得:(2∗close−low−high)/(close−low)
我们深入研究该因子可以发现:
(2∗close−low−high)/(close−low)=1−(high−close)/(close−low)
前面的常数1可以通过delta消掉,其实可以简化为(high−close)/(close−low)的现值-9天之前的值
而(high−close)/(close−low)本身则代表了收盘价在日内波动中的位置,可以看做是买入意愿的一种体现
我们强烈建议大家在实现这些Formulaic Alpha因子之前先花一些精力去理解其经济含义,不仅可以加深对其原理的理解,在某些时候还可以简化实现。
我们以论文中的Alpha 26为例,其原始表达式为:
−1∗ts_max(correlation(ts_rank(volume,5),ts_rank(high,5),5),3)
我们当然可以按照其原始表达式一步步地先对过去5天的成交量和最高价进行排名,再取相关系数;但是较熟悉Pandas DataFrame内置函数或者统计知识较丰富的研究者可以发现,correlation(ts_rank(volume,5),ts_rank(high,5),5) 其实就是在计算Spearman Rank Correlation Coefficient,使用DataFrame内置的corr(method="spearman")函数就可以完成计算,可以大大提高开发效率。
在我们的模拟的过程中发现,如果按照原公式进行计算,无论是long还是short的结果都跑不赢大盘,同时对于成交量和最高价相关性较高的将会是市场追逐的热点,应该分配更大的权重。
所以在上述代码中我们将原Formulaic Alpha前面的负号去掉。
当然,对于论文中出现的某些因子可能较难于理解其经济学意义,我们鼓励大家用Quartz Signal将其实现之后发到社区上与大家一起讨论。
对于Quartz Signal模块有哪些不尽如人意的地方也可以反馈给我们,帮助我们持续改进。
1、函数定义
①使用def关键字定义函数
②
def 函数名(参数1.参数2.参数3...):
"""文档字符串,docstring,用来说明函数的作用"""
#函数体
return 表达式
注释的作用:说明函数是做什么的,函数有什么功能。
③遇到冒号要缩进,冒号后面所有的缩进的代码块构成了函数体,描述了函数是做什么的,即函数的功能是什么。Python函数的本质与数学中的函数的本质是一致的。
2、函数调用
①函数必须先定义,才能调用,否则会报错。
②无参数时函数的调用:函数名(),有参数时函数的调用:函数名(参数1.参数2.……)
③不要在定义函数的时候在函数体里面调用本身,否则会出不来,陷入循环调用。
④函数需要调用函数体才会被执行,单纯的只是定义函数是不会被执行的。
⑤Debug工具中Step into进入到调用的函数里,Step Into My Code进入到调用的模块里函数。
关于编程,有三种方式
1、面向对象编程----类 关键字:class
2、面向过程编程----过程 关键字:def
3、函数式编程------函数 关键字:def
函数式编程:函数是逻辑化结构化和过程化的一种编程方式,如
def test(x):
"xxxxx"
x+=1
return x
def:定义函数的关键字
test:函数名称
(x):传入函数的参数
x+=1:泛指逻辑处理块代码
"xxxx"函数描述(非必要,但强列建议添加)
定义一个过程,过程无返回值
def fun1():
"fun1"
print('fun1')
定义一个函数,函数有返回值
def fun2():
"fun2"
print('fun2')
return 0
函数和过程的调用是一致的:
fun1
fun2
在python中,过程就是一个没有返回值的函数,过程默认返因一个none,当函数有多个返回值时,将返回元组,这些值将被当做一个元组的元素,即:
返回值个数0:返回NONE
返回值个数1:返回object
返回值个数多个:返回元组
函数的功能:没有函数的编程只是在写逻辑(功能),脱离函数,重用逻辑(实现功能),唯一的方式就是复制粘贴,使用函数后简化代码,可读性变高,易扩展(保持一致性)
在定义函数时的参数,我们称为行参,如下面的x,y
而调用函数时传入的参数,我们称之为实参,如下面的1、2。
def test(x,y)
print(x)
print(y)
test(1,2)
位置调用时行参与实参的位置关系是一一对应的
def test(x,y)
print(x)
print(y)
test(1,2)
关键字调用时,与实参的位置无关如
def test(x,y)
print(x)
print(y)
test(y=2,x=3)
当位置调用与关键字调用混用时,按照位置调用方式执行,但要记位一句话,关键字参数不能写在位置参数前面,即test(3,y=2,6)此种方式将会报错,应写成test(3,2,z=6)或test(3,z=2,y=6)
当函数中有默认的参数值时如
def test(x,y=1)
.....
return 0
当调用这个函数时,如果不传入y的值时,y的值将采用默认值,如果传入新的y的值时,默认y的值将被覆盖。
默认值使用的场合:
1、软件安装的时候
2、连接数据库的端口
等
参数组:当行参或实参数量不固定的时候时使用,可与默认参数或行参混用,参数组一定要最至最后
def test(*args)#接收N个位置参数 #def test(name,*args) #def test(name,age=1,*args)
print(args)
test(1,2,3,4,5……)
test(*[1,2,3,4……])
最终实参会被变成一个元组如:
def fun(agr1,agr2,*args)
pass
fun(1,2,3,4,5)
====结果=====
1,2,(3,4,5)
这种方式是预留以后当需要传多个参数时使用而不变动太多的代码
传入不定数量字典时:把N个关键字参数转换成字典的方式,可与默认参数或行参混用,参数组一定要最至最后
def test(agrs1,agrs2,**kwargs) #接收N个关键字参数
# print(kwagrs)
# print(kwagrs['name'])
# print(kwagrs['age'])
pass
test(3,5,name='a',age=23,sex='F')#以关键字的方式传值
=====结果====
3,5,{'name':'a','age':23,'sex':'f'}
test(**{name:'a',age:8,sex:'F'})
###位置参数不能写在关键字参数后面,否则程序会报错
函数调用函数
def test1()
print......
def test2()
print...
test1() #调用test1
print(test2()) #调用