第三章:Python 编程

时间:2021-05-11 18:37:54
第一节:Python 介绍 






一、Python 简介 






    Python 是一种计算机程序设计语言。你可能已经听说过很多种流行的编程语言,比如非 


常难学的 C 语言,非常流行的 Java 语言,适合初学者的Basic 语言,适合网页编程的 


JavaScript 语言等等。 






    那Python 是一种什么语言? 






    Python  的创史人 Guido van Rossum ,1989 年在荷兰创造了python ,网络流传是因为他 


喜欢英国肥皂剧 《Monty Python 飞行马戏团》,所以用python 来命名。 






    语言分为编译型语言和解释型语言,python 是一门解释型语言,何为解释型语言; 






    编译型语言:c、c++等 


    解释型语言有:Python 、Php 等 






    以下表格是两类语言的优缺点介绍 






语言        优点                            缺点 






解释型语言  可跨平台、开发效率高                       运行效率低 






编译型语言  依赖编译平台,不能跨平台,开发效率低 运行效率高 






     


    比如,完成同一个任务,C 语言要写1000 行代码,Java 只需要写100 行,而Python 可 


能只要 20 行。 






    所以Python 是一种相当高级的语言。 






    你也许会问,代码少还不好?代码少的代价是运行速度慢,C 程序运行 1 秒钟,Java 程 


序可能需要 2 秒,而Python 程序可能就需要 10 秒。 






    那是不是越低级的程序越难学,越高级的程序越简单?表面上来说,是的,但是,在非 


常高的抽象计算中,高级的Python 程序设计也是非常难学的,所以,高级程序语言不等于 


简单。 






    但是,对于初学者和完成普通任务,Python 语言是非常简单易用的。连Google 都在大 


规模使用 Python ,你就不用担心学了会没用。 




----------------------- Page 30-----------------------


二、第一个 Python 程序 






    作为初学者,学习一门新语言,尝试写一个程序,可以快速进入状态,第一个程序 


叫'Hello MindGo' 。在Python 中,它是这个样子: 


print('Hello MindGo') 


Hello MindGo 






    这是 print()语句的一个示例。print 并不会真的往纸上打印文字,而是在屏幕上输出值。 


程序中引号内的内容表示需要输出的内容,而引号在输出结果中并不显示。 






    print()语句也可以跟上多个字符串,用逗号 “,”隔开,就可以连成一串输出: 






print ('This', 'is', 'an','apple') 


This is an apple 






    print()也可以打印整数,或者计算结果: 






print(300) 


300 


print(100 + 200) 


300 






    让我们可以把计算 100 + 200 的过程和结果都打印出来试试: 






print('100 + 200 =', 100 + 200) 


100 + 200 = 300 






三、变量 






    编程语言最强大的功能之一是操作变量的能力。变量是指向一个值的名称。 


    赋值语句可以建立新的变量,并给他们赋值: 


quant = 'Hello MindGo' 


x = 500 






    这个例子有两个赋值。第一个将字符串'Hello MindGo'赋值给一个叫做 quant 的变量;第 


二个将500 赋值给x 。 


    他的状态图如下所示: 




----------------------- Page 31-----------------------


四、两项基本操作 






    了解下面两个基本操作对后面的学习是有好处的: 






1.基本的输入输出 






    可以在Python 中使用+ 、-、*、/直接进行四则运算。 






1+3*3 






10 






2.导入模块 






    使用 import 可以导入模块,导入之后,就可以使用这个模块下面的函数了。 


    比如导入 math 模块,然后使用math 模块下面的sqrt 函数: 






import math 


math.sqrt(9) 






3.0 






    这时你可能会有疑问: 


    “每次引用函数的时候,math 这个模块前缀都要带吗?可不可以不带?” 


    直接输入 sqrt(9)是会报错的,好烦人,那么有什么办法可以不用每次都带前缀? 


    办法是有的,用“from 模块 import 函数”的格式先把函数给 “拿”出来。 






from math import sqrt 


sqrt(9) 






3.0 






    这样每次使用 sqrt 函数的时候就不用再加math 前缀了。又有了一个问题? 


    “math 模块下面有那么多函数,可不可以写一个语句,然后math 下面所有函数都可以 


直接使用?” 


    调用了 math 下面的sqrt 函数,写一个 from…import…,再调用下面的floor,还要写一 


个,如此也挺麻烦的,有个办法可以一下把所有函数都给 “拿”出来: 






from math import * 


print(sqrt(9)) 


print(floor(32.9)) 






3.0 


32.0 




----------------------- Page 32-----------------------


第二节:数据类型 






一、什么是数据结构 






    开始学Python 时,经常会被它的数据结构,什么字典、序列、元组等等搞的很混乱, 


因此有必要梳理清楚数据结构的概念。 






    首先要从容器说起,Python 中有一种名为容器的数据结构,顾名思义,容器,就是装数 


据的器具,它主要包括序列和词典,其中序列又主要包括列表、元组、字符串等,如下图: 






    列表的基本形式比如:[1,3,6,10]或者[‘yes’,’no’,’OK’] 


    元组的基本形式比如:(1,3,6,10)或者(‘yes’,’no’,’OK’) 


    字符串的基本形式比如:'Hello ' 






    以上几种属于序列,序列中的每一个元素都被分配一个序号——即元素的位置,也称为 


 “索引”,第一个索引,即第一个元素的位置是 0,第二个是 1,依次类推。列表和元组的 


区别主要在于,列表可以修改,而元组不能 (注意列表用中括号而元组用括号)。序列的这 


个特点,使得我们可以利用索引来访问序列中的某个或某几个元素,比如: 


a=[1,3,6,10] 


a[2] 













b=(1,3,6,10) 


b[2] 













c='hello' 


c[0:3] 






'hel' 






     




----------------------- Page 33-----------------------


    而与序列对应的“字典”则不一样,它是一个无序的容器: 


    它的基本形式比如:d={7:‘seven’,8:‘eight’,9:‘nine’} 


    这是一个“键—值”映射的结构,因此字典不能通过索引来访问其中的元素,而要根据 


键来访问其中的元素: 






d={7:'seven',8:'eight',9:'nine'} 


d[8] 






'eight' 






二、序列的一些通用操作 






    除了上面说到的索引,列表、元组、字符串等这些序列还有一些共同的操作。 






1.索引 






    序列的最后一个元素的索引,也可以是-1,倒数第二个也可以用-2,依次类推: 






a=[1,3,6,10] 


print(a[3]) 


print(a[-1]) 






10 


10 






2.分片 






    使用分片操作来访问一定范围内的元素,它的格式为: 


    a[开始索引:结束索引:步长] 


    那么访问的是,从开始索引号的那个元素,到结束索引号-1 的那个元素,每间隔步长个 


元素访问一次,步长可以忽略,默认步长为 1。 






c='hello' 


c[0:3] 






'hel' 


     


    这个就好像把一个序列给分成几片几片的,所以叫做“分片” 




----------------------- Page 34-----------------------


3.序列相加 






     即两种序列合并在一起,两种相同类型的序列才能相加。 






[1,2,3]+[4,5,6] 






[1, 2, 3, 4, 5, 6] 






'hello,'+'MindGo' 






'hello,MindGo' 






4.成员资格 






    为了检查一个值是否在序列中,可以用in 运算符 






a='hello' 


print('o' in a) 


print('t' in a) 






True 


False 






三、列表操作 






    以上是序列共有的一些操作,列表也有一些自己独有的操作,这是其他序列所没有的 






1.List 函数 






    可以通过 list(序列)函数把一个序列转换成一个列表: 






list('hello') 






['h', 'e', 'l', 'l', 'o'] 






2.元素赋值、删除 






    元素删除——del a[索引号] 


    元素赋值——a[索引号]=值 






a='hello' 


b=list(a) 


print(b) 






['h', 'e', 'l', 'l', 'o'] 






del b[2] 


print(b) 






['h', 'e', 'l', 'o'] 




----------------------- Page 35-----------------------


b[2]='t' 


print(b) 






['h', 'e', 't', 'o'] 






    分片赋值——a[开始索引号:结束索引号]=list(值) 






    为列表的某一范围内的元素赋值,即在开始索引号到结束索引号-1 的区间几个元素赋值, 


比如,利用上面语句,如何把hello 变成heyyo ? 






b=list('hello') 


print(b) 


['h', 'e', 'l', 'l', 'o'] 






b[2:4]=list('yy') 


print(b) 






['h', 'e', 'y', 'y', 'o'] 






    注意虽然 “ll”处于“hello”这个单词的第2 、3 号索引的位置,但赋值时是用b[2:4]而不 


是b[2:3] ,另外注意list()用小括号。 






3.列表方法 






    上面说过 list 函数,函数这个东西在很多语言中都有,比如excel 里面的if 函数、 


vlookup 函数,SQL 里面的count 函数,以及各种语言中都有的sqrt 函数等等,python 中也有 


很多函数。 






    Python 中的方法,是一个“与某些对象有紧密联系的”函数,所以列表方法,就是属于 


列表的函数,它可以对列表实现一些比较深入的操作,方法这样调用:对象.方法(参数) 






    那么列表方法的调用就理所当然是:列表.方法(参数) 


    常用的列表方法这么几个,以 a=[‘h’,‘e’,‘l’,‘l’,‘o’]为例: 






a=['h','e','l','l','o'] 


print(a) 






['h', 'e', 'l', 'l', 'o'] 






    给列表a 的n 索引位置插入一个元素m:  a.insert(n,m) 


a.insert(2,'t') 


print(a) 






['h', 'e', 't', 'l', 'l', 'o'] 






    给列表的最后添加元素m: a.append(m) 


a.append('q') 


print(a) 






['h', 'e', 't', 'l', 'l', 'o', 'q'] 




----------------------- Page 36-----------------------


    返回a 列表中,元素m 第一次出现的索引位置: a.index(m) 


a.index('e') 









    删除a 中的m 元素: a.remove(m) 


a.remove('e') 


print(a) 


['h', 't', 'l', 'l', 'o', 'q'] 


    将列表a 从大到小排列: a.sort() 


a.sort() 


print(a) 






['h', 'l', 'l', 'o', 'q', 't'] 






四、字典操作 






1.dict 函数 






    dict 函数可以通过关键字参数来创建字典,格式为: 


    dict(参数 1=值 1,参数 2=值 2, …)={参数 1:值 1, 参数 2=值 2, …} 


    比如,如何创建一个名字name 为 quanter ,年龄age 为 22 的字典? 






dict(name='quanter',age=22) 






{'age': 22, 'name': 'quanter'} 






2.基本操作 






    字典的基本行为与列表在很多地方都相似,下面的例子以序列a=[1,3,6,10],字典 


f={‘age’: 27, ‘name’: ‘shushuo’}为例 




----------------------- Page 37-----------------------


第三节:条件与循环 






一、if 语句 






    注意两点,一是缩进,Python 是用缩进来标识出哪一段属于本循环。,二是条件后面有 


 冒号: 


j=2.67 


if j<3: 


    print('j<3') 






j<3 


     


    对于多条件,要写成elif,标准格式为: 


if 条件 1: 


 执行语句1 


elif 条件 2: 


 执行语句2 


else: 


 执行语句3 


     


    注意if…elif…else 三个是并列的,不能有缩进: 


t=3 


if t<3: 


    print('t<3') 


elif t==3: 


    print('t=3') 


else: 


    print('t>3')  






t=3 






二、while true/break 语句 






    该语句的格式为 


while true 即条件为真: 


     执行语句 


     if 中断语句条件 : break 






    看个例子: 


a=3 


while a<10: 


    a=a+1 


    print(a) 


    if a==8: break 


         







----------------------- Page 38-----------------------


















    虽然while 后面的条件是a<10,即a 小于 10 的时候一直执行,但是 if 条件中规定了 a 为 


8 时就break 掉,因此,输出只能输到8。 






三、for 语句 






    可以遍历一个序列/字典等。 


a=[1,2,3,4,5] 


for i in a: 


    print(i) 



















----------------------- Page 39-----------------------


第四节:函数 






    函数是组织好的,可重复使用的,用来实现单一,或相关联功能的代码段。函数能提高 


应用的模块性,和代码的重复利用率。 






一、调用函数 






    Python 内置了很多有用的函数,我们可以直接调用。 


    要调用一个函数,需要知道函数的名称和参数,比如求绝对值的函数 abs,只有一个参 


数。 


    调用 abs 函数: 


abs(-100) 






100 






    调用函数的时候,如果传入的参数数量不对,会报TypeError 的错误,并且Python 会明 


确地告诉你:abs()有且仅有1 个参数,但给出了两个: 


abs(1, 2) 


--------------------------------------------------------------------------- 


TypeError                                 Traceback (most recent call last) 


<ipython-input-22-05b55862d84c> in <module>() 


----> 1 abs(1, 2) 






TypeError: abs() takes exactly one argument (2 given) 


     


    如果传入的参数数量是对的,但参数类型不能被函数所接受,也会报TypeError 的错误, 


并且给出错误信息:str 是错误的参数类型: 


abs('a') 


--------------------------------------------------------------------------- 


TypeError                                 Traceback (most recent call last) 


<ipython-input-23-3b9a69fe3abb> in <module>() 


----> 1 abs('a') 






TypeError: bad operand type for abs(): 'str' 






二、定义函数 






    在Python 中,定义一个函数要使用 def 语句,依次写出函数名、括号、括号中的参数和 


冒号:,然后,在缩进块中编写函数体,函数的返回值用return 语句返回。 


我们以自定义一个求绝对值的 abs_my 函数为例: 






def abs_my(x): 


    if x >= 0: 


        return x 


    else: 


        return -x 






    测试并调用 abs_my 看看返回结果是否正确: 




----------------------- Page 40-----------------------


abs_my(-100) 






100 






    请注意,函数体内部的语句在执行时,一旦执行到return 时,函数就执行完毕,并将结 


果返回。因此,函数内部通过条件判断和循环可以实现非常复杂的逻辑。 






    如果没有return 语句,函数执行完毕后也会返回结果,只是结果为None 。 


    return None 可以简写为return 。 






三、函数的参数 






    定义函数的时候,我们把参数的名字和位置确定下来,函数的接口定义就完成了。对于 


函数的调用者来说,只需要知道如何传递正确的参数,以及函数将返回什么样的值就够了, 


函数内部的复杂逻辑被封装起来,调用者无需了解。 






    Python 的函数定义非常简单,但灵活度却非常大。除了正常定义的必选参数外,还可以 


使用默认参数、可变参数和关键字参数,使得函数定义出来的接口,不但能处理复杂的参数, 


还可以简化调用者的代码。 






3.1 默认参数 






    我们仍以具体的例子来说明如何定义函数的默认参数。先写一个计算y 的平方的函数: 


def power(y): 


    return y * y 


    当我们调用 power  函数时,必须传入有且仅有的一个参数 y : 


power(5) 


25 


    现在,如果我们要计算 y3 怎么办?可以再定义一个power3 函数,但是如果要计算 


y4 、y5……怎么办?我们不可能定义无限多个函数。 


    函数中再添加一个参数即可帮助我们搞定这个问题 ! 






def power(y, t): 


    d = 1 


    while t > 0: 


        t = t - 1 


        d = d * y 


    return d 


    对于这个修改后的 power  函数,可以计算任意 n 次方: 


power(5, 3) 






125 


     




----------------------- Page 41-----------------------


    但是,旧的调用代码失败了,原因是我们增加了一个参数,导致旧的代码无法正常调用: 


power(5) 






--------------------------------------------------------------------------- 


TypeError                                 Traceback (most recent call last) 


<ipython-input-28-cacc59fd9139> in <module>() 


      5         d = d * y 


      6     return d 


----> 7 power(5) 






TypeError: power() missing 1 required positional argument: 't'   


    这个时候,默认参数就排上用场了。由于我们经常计算 y 的平方,所以,完全可以把第 


二个参数 n  的默认值设定为 2 : 


def power(y, t=2): 


    d = 1 


    while t > 0: 


        t = t - 1 


        d = d * y 


    return d 


    这样,当我们调用 power(5)  时,相当于调用 power(5, 2) : 


power(5) 


25 






power(5, 2) 


25 


    而对于 n > 2  的其他情况,就必须明确地传入 n ,比如 power(5, 3) 。 


    从上面的例子可以看出,默认参数可以简化函数的调用。设置默认参数时,有几点要注 


意: 


    一、必选参数在前,默认参数在后,否则Python 的解释器会报错。 


    二、如何设置默认参数。当函数有多个参数时,把经常改动的参数放前面,不经常改动 


的参数放后面。不经常改动的参数就可以作为默认参数。 


    使用默认参数有什么好处?最大的好处是能降低调用函数的难度。 


3.2 可变参数 






    在Python 函数中,还可以定义可变参数。顾名思义,可变参数就是传入的参数个数是 


可变的,可以是 1 个、2 个到任意个,还可以是 0 个。 


    我们以数学题为例子,给定一组数字a,b ,c……,请计算 a+b+c+…… 。 


    要定义出这个函数,我们必须确定输入的参数。由于参数个数不确定,我们首先想到可 


以把a,b ,c……作为一个 list 或 tuple 传进来,这样,函数可以定义如下: 


def sum_my(n): 


    d = 0 


    for n in n: 


        d = d + n  


    return d 


    但是调用的时候,需要先组装出一个 list 或 tuple : 


sum_my([1, 2, 3]) 











----------------------- Page 42-----------------------


sum_my((1, 3, 5, 7)) 






16 


    如果利用可变参数,我们把函数的参数改为可变参数: 


def sum_my(*n): 


    d = 0 


    for n in n: 


        d = d + n  


    return d 


    调用函数的方式可以简化成这样: 


sum_my(1, 2, 3) 













sum_my(1, 3, 5, 7) 






16 


    定义可变参数和定义 list 或 tuple 参数相比,仅仅在参数前面加了一个 * 号。在函数内 


部,参数 numbers 接收到的是一个 tuple ,因此,函数代码完全不变。但是,调用该函数时, 


可以传入任意个参数,包括 0 个参数: 


sum_my() 









    如果已经有一个 list 或者 tuple ,要调用一个可变参数怎么办? Python 允许你在 list 或 


tuple 前面加一个 * 号,把 list 或 tuple  的元素变成可变参数传进去,可以这样做: 


number = [1, 2, 3] 


sum_my(*number) 









    这种写法相当有用,而且很常见。 






3.3 关键字参数 






    可变参数允许你传入 0 个或任意个参数,这些可变参数在函数调用时自动组装为一个  


tuple 。而关键字参数允许你传入 0 个或任意个含参数名的参数,这些关键字参数在函数内 


部自动组装为一个 dict 。请看示例: 






def myclass(name, number, **other): 


    print('name:', name, 'number:', number, 'other:', other) 


    函数 myclass 除了必选参数 name 和 number 外,还接受关键字参数 other 。在调用该函 


数时,可以只传入必选参数: 


myclass('Lili',4001) 


name: Lili number: 4001 other: {}         


    也可以传入任意个数的关键字参数: 


myclass('yunyun', 4012, gender='girl', age='23') 


name: yunyun number: 4012 other: {'gender': 'girl', 'age': '23'}         


    关键字参数有什么用?它可以扩展函数的功能。比如,在myclass 函数里,我们保证能 


接收到name 和 age 这两个参数,但是,如果调用者愿意提供更多的参数,我们也能收到。 




----------------------- Page 43-----------------------


试想你正在做一个用户注册的功能,除了用户名和年龄是必填项外,其他都是可选项,利用 


关键字参数来定义这个函数就能满足注册的需求。 






3.4 混合参数 






    在Python 中定义函数,可以用必选参数、默认参数、可变参数和关键字参数,这 4 种参 


数都可以一起使用,或者只用其中某些,但是请注意,参数定义的顺序必须是:必选参数、 


默认参数、可变参数和关键字参数。 


    比如定义一个函数,包含上述4 种参数: 


def number(a, b=0, *c, **d): 


    print('a =', a, 'b =', b, 'c =', c, 'd =', d) 


    同学们在记忆时,可尝试对应四个选项,采用巧记的方式:a 是 a,b 为 0,c 前一颗星,d 


前两颗星,a 必须定义,b 默认为 0,c 可多定义,d 为小字典,可额外补充。 






    在函数调用的时候,Python 解释器自动按照参数位置和参数名把对应的参数传进去。 


number(1,2,3,3,d=4) 


a = 1 b = 2 c = (3, 3) d = {'d': 4} 




----------------------- Page 44-----------------------


第五节:numpy 






    Numpy 是高性能科学计算和数据分析的基础包。Numpy 本身并没有提供多么高级的数 


据分析功能,理解 Numpuy 数组以及面向数组的计算将有助于你提高处理数据能力。本节 


内容介绍 ndarray 数组和矩阵。 






一、ndarray 数组基础 






    使用 ndarray 数组,需要导入 Numpy  函数库。 


    导入方法 1:直接导入该函数库: 


from numpy import * 


    导入方法 2 :指定导入库的别名 (在引入多个库的时候,推荐使用这个方法)。 


import numpy as np 


    下面正式进入Numpy 的数组世界。如果没有说明,所称数组均为 Numpy 数组对象,与 


Python  的列表和 array 模块无关。 






1.1 创建数组 






    创建数组是进行数组计算的第一步,可以通过numpy 库包内的array()函数定义数组实例 


对象,其参数为 Python  的序列对象,如果想定义多维数组,则传递多层嵌套的序列。 


    例如下面这条语句定义了一个二维数组,其大小为 (2,3 ),即有2 行,3 列。 


a = np.array([[1,2,3.0],[2,3,4.0]]) 


print(a) 






[[ 1.  2.  3.] 


 [ 2.  3.  4.]] 


    以下三种操作,可以帮助我们查看数组的一些属性: 


    查看行数使用 ndim 


a.ndim 









    查看数组的维数使用 shape,返回(n,m), 其中 n 为行数,m 为列数。 


a.shape 






(2, 3) 


    查看元素的类型使用 dtype ,比如 numpy.int32 、numpy.float64 


a.dtype 






dtype('float64') 






1.2 特殊数组 






    Numpy 的特殊数组主要有以下三种: 






    zeros 数组:全零数组,元素全为 0 ; 


    ones 数组:全1 数组,元素全为 1; 


    empty 数组:空数组,元素全近似为 0 ; 


    创建方法分别为: 




----------------------- Page 45-----------------------


zeros 数组 


np.zeros((2,5)) 


array([[ 0.,  0.,  0.,  0.,  0.], 


       [ 0.,  0.,  0.,  0.,  0.]]) 


ones 数组 


np.ones((6,7)) 


array([[ 1.,  1.,  1.,  1.,  1.,  1.,  1.], 


       [ 1.,  1.,  1.,  1.,  1.,  1.,  1.], 


       [ 1.,  1.,  1.,  1.,  1.,  1.,  1.], 


       [ 1.,  1.,  1.,  1.,  1.,  1.,  1.], 


       [ 1.,  1.,  1.,  1.,  1.,  1.,  1.], 


       [ 1.,  1.,  1.,  1.,  1.,  1.,  1.]]) 


empty 数组 


np.empty((3,3)) 






array([[  6.94415038e-310,   6.94415038e-310,   6.94415038e-310], 


       [  6.94415038e-310,   6.94415038e-310,   6.94415038e-310], 


       [  6.94415038e-310,   6.94415039e-310,   6.94415038e-310]]) 






1.3 序列数组 






    arange 函数:属于Numpy 库,其参数依次为:开始值、结束值、步长。 






np.arange(1,100,5) 






array([ 1,  6, 11, 16, 21, 26, 31, 36, 41, 46, 51, 56, 61, 66, 71, 76, 81, 


       86, 91, 96]) 


    linspace 函数创建等差序列数组,其参数依次为:开始值、结束值、元素数量。 


np.linspace(1,100,5) 






array([   1.  ,   25.75,   50.5 ,   75.25,  100.  ]) 






1.4 数组索引 






    Numpy 数组的每个元素、每行元素、每列元素都可以用索引访问。注意:索引是从 0  


开始的。 


    其操作与列表基本相同,以下是三种操作方式。 


a = np.array([[1,2,4.0],[3,6,9]]) 


1.取 a  的第一行元素 


a[0] 






array([ 1.,  2.,  4.]) 


2.取 a  的第二列元素 


a[:,1] 






array([ 2.,  6.]) 




----------------------- Page 46-----------------------


3.取 a  的第一行的第三个元素 


a[0,2] 






4.0 






1.5 数组运算,以下介绍 10 种常用运算 






a = np.array([1,2,3]) 


b = np.array([4.,5,6]) 


1.加法运算 


a + b 






array([ 5.,  7.,  9.]) 


2.减法运算 


a - b 


array([-3., -3., -3.]) 


3.乘法运算 


a * b 






array([  4.,  10.,  18.]) 


4.乘方运算:a 的2 次方 


a ** 2 






array([1, 4, 9]) 


5.除法运算 


a/b 






array([ 0.25,  0.4 ,  0.5 ]) 


6.数组点乘 






np.dot(a,b) 






32.0 


7.判断大小,返回 bool 值 


a >= 2 






array([False,  True,  True], dtype=bool) 


8.a 中最大的元素 


a.max() 









9.a 中最小的元素 


a.min() 









10.a 的和 


a.sum() 











----------------------- Page 47-----------------------


1.6 数组拷贝 






    数组的拷贝分为浅拷贝和深拷贝两种,浅拷贝通过数组变量的复制完成,深拷贝使用数 


组对象的copy 方法完成。 


    浅拷贝只拷贝数组的引用,如果对拷贝对象修改。原数组也将修改。 






    以下是浅拷贝的演示: 


a = np.ones((2,3)) 






print(a) 






[[ 1.,  1.,  1.], 


 [ 1.,  1.,  1.]] 


    b 为 a  的浅拷贝 


b = a 






print(b) 






[[ 1.,  1.,  1.], 


 [ 1.,  1.,  1.]] 


    对 b 进行修改,a 也会被修改 


b[1,2] = 9 






print(a) 






[[ 1.  1.  1.] 


 [ 1.  1.  9.]] 


     


    以下是深拷贝的演示: 


    深拷贝会复制一份和原数组一样的数组,但他们在内存中是分开存放的,所以改变拷贝 


数组,原数组不会改变。 


a = np.ones((2,3)) 






print(a) 






[[ 1.  1.  1.] 


 [ 1.  1.  1.]] 






b = a.copy() 






b[1,2] = 9 






print(b) 






[[ 1.,  1.,  1.], 


 [ 1.,  1.,  9.]] 






print(a) 


[[ 1.,  1.,  1.], 


 [ 1.,  1.,  1.]] 




----------------------- Page 48-----------------------


二、矩阵 






2.1 创建矩阵 






    Numpy 的矩阵对象与数组对象相似,主要不同之处在于,矩阵对象的计算遵循矩阵数 


学运算规律。 


    矩阵使用 matrix  函数创建,以 (2,2 )大小的矩阵为例 (2 行2 列),定义方法如下: 


a = np.matrix([[1.0,2.0],[3.0,4.0]]) 


print(a) 






[[ 1.  2.] 


 [ 3.  4.]] 


    type 函数可以查看 a 的类型 


type(a)  






numpy.matrixlib.defmatrix.matrix 






2.2 矩阵运算 






    矩阵的常用数学运算有转置、乘法、求逆等。分别一一实例讲述。 


    创建一个矩阵 


b=np.matrix([[4.0,6.0],[2.0,8.0]]) 


print(b) 






[[ 4.  6.] 


 [ 2.  8.]] 


1.转置操作 


b.T 






matrix([[ 4.,  2.], 


        [ 6.,  8.]]) 


2.矩阵乘法 


c=np.matrix([[2.0,2.0],[2.0,2.0]]) 


b*c 






matrix([[ 20.,  20.], 


        [ 20.,  20.]]) 


3.逆矩阵 


b.I 


matrix([[ 0.4, -0.3], 


        [-0.1,  0.2]]) 




----------------------- Page 49-----------------------


第六节:pandas 基础 






    pandas 是基于 Numpy 构建的,让以 Numpy 为中心的应用变得更加简单。pandas 是公 


认的数据处理利器,本章内容主要介绍 DataFrame 数据结构,在此基础上进行数据处理。除 


了DataFrame 格式,pandas 还包括series、Panel 。 






 格式             数组                         释义 






 Series         一维数组                       与Numpy 中的一维array 类似。 






 DataFrame      二维的表格型数据结构                 可以将DataFrame 理解为 Series 的容器 






 Panel          三维的数组                      可以理解为DataFrame 的容器 






     


    开始之前,我们首先掌握导入pandas 库,方式如下: 


import pandas as pd 


    注意:以下内容必须在导入pandas 库之后才能运行。 






一、Series 和 DataFrame 介绍 






1.Series 






    由一组数据和与之相关的索引组成。可通过传递一个 list 对象来创建一个 Series,pandas 


会默认创建整型索引。 


    创建一个 Series: 


s = pd.Series([1,3,5,7,6,8]) 






print(s) 






0    1 


1    3 


2    5 


3    7 


4    6 


5    8 


dtype: int64 


获取 Series 的索引: 


s.index 






RangeIndex(start=0, stop=6, step=1) 






2.DataFrame 






    DataFrame 是一个表格型的数据结构,它含有一组有序的列,每一列的数据结构都是相 


同的,而不同的列之间则可以是不同的数据结构。DataFrame 中的每一行是一个记录,名称 


为 Index 的一个元素,而每一列则为一个字段,是这个记录的一个属性,DataFrame 既有行 


索引也有列索引。 






    创建DataFrame 


    首先来看如何从字典创建DataFrame 。 




----------------------- Page 50-----------------------


d = {'one': [1, 2, 3], 'two': [1, 2, 3]} 


df = pd.DataFrame(d,index=['a', 'b', 'c']) 


print(df) 






   one  two 


a    1    1 


b    2    2 


c    3    3 


    可以使用 dataframe.index 和 dataframe.columns 来查看 DataFrame 的行和列, 


dataframe.values 则以数组的形式返回DataFrame 的元素: 


print(df.index) #查看行 


print(df.columns) #查看列 


print(df.values) #查看元素 






Index(['a', 'b', 'c'], dtype='object') 


Index(['one', 'two'], dtype='object') 


[[1 1] 


 [2 2] 


 [3 3]] 


    DataFrame 从值是数组的字典创建时,其各个数组的长度需要相同,加强印象,可参考 


以下报错的例子。 


d = {'one': [1, 2], 'two': [1, 2, 3]} 


df = pd.DataFrame(d,index=['a', 'b', 'c']) 


print(df) 






ValueError: Shape of passed values is (2, 2), indices imply (2, 3) 


    如果DataFrame 的值是非数组时,没有这一限制,且自动将缺失值补成NaN 。如下示例 


d= [{'a': 1.6, 'b': 2}, {'a': 3, 'b': 6, 'c': 9}] 


df = pd.DataFrame(d) 


print(df) 






     a  b    c 


0  1.6  2  NaN 


1  3.0  6  9.0 


    在实际处理数据时,有时需要创建一个空的DataFrame ,可以这么做: 


df = pd.DataFrame() 


print(df) 






Empty DataFrame 


Columns: [] 


Index: []  




----------------------- Page 51-----------------------


    另一种创建DataFrame 的方法十分有用,那就是使用 concat 函数创建DataFrame ,其主 


要是通过两个行或列相同的 DataFrame 链接成一个。 


a= [{'a': 1.6, 'b': 2}, {'a': 3, 'b': 6}] 


df1 = pd.DataFrame(a) 


b= [{'a': 4, 'b': 5}] 


df2 = pd.DataFrame(b) 


df = pd.concat([df1, df2], axis=0) 


print(df1) 


print(df2) 


print(df) 






     a  b 


0  1.6  2 


1  3.0  6 






   a  b 


0  4  5 






     a  b 


0  1.6  2 


1  3.0  6 


0  4.0  5 


    注意:concat 函数内有axis 参数,其中的axis=1 表示按列进行合并,axis=0 表示按行合 


并 






二、数据查看  






    MindGO 量化交易平台上大部分获取数据的函数,最终以DataFrame 或Dict(字典)格式 


呈现。接下来重点介绍 DataFrame 格式的数据查看,数据处理。以 MindGO 平台获取的数据 


为例进行讲解: 


    该部分内容需在MindGo 研究环境中练习。 






# 获取贵州茅台近10 个工作日的开盘价、最高价、最低价、收盘价,获取格式即为 


DataFrame 


price= get_price('600519.SH', None, '20180125', '1d', ['open', 'high', 'low', 'close'], False, 'pre', 20,  


is_panel=1) 


print(price) 






             close    high     low    open 


    2017-12-28  718.69  719.90  671.32  687.00 


    2017-12-29  697.49  726.50  691.60  718.00 


    2018-01-02  703.85  710.16  689.89  700.00 


    2018-01-03  715.86  721.40  699.74  701.50 


    2018-01-04  737.07  743.50  719.33  721.40 


    2018-01-05  738.36  746.03  728.22  741.00 


    2018-01-08  752.13  756.50  735.02  735.02 


    2018-01-09  782.52  783.00  752.21  752.21 


    2018-01-10  785.71  788.88  773.48  785.00 


    2018-01-11  774.81  788.00  772.00  787.00 




----------------------- Page 52-----------------------


      2018-01-12  788.42  788.80  767.02  773.77 


      2018-01-15  785.37  799.06  779.02  793.46 


      2018-01-16  772.94  788.61  768.00  780.48 


      2018-01-17  747.93  774.00  738.51  770.00 


      2018-01-18  750.74  765.00  744.09  747.93 


      2018-01-19  750.18  758.90  739.02  752.90 


      2018-01-22  773.64  774.00  751.81  751.81 


      2018-01-23  773.78  780.00  768.60  777.81 


      2018-01-24  764.46  776.46  758.60  776.44 


      2018-01-25  769.16  776.00  751.00  761.00 


    以下为数据查看常用的八项操作: 






1.查看前几条数据: 


price.head() 






             close    high     low   open 


2017-12-28  718.69  719.90  671.32  687.0 


2017-12-29  697.49  726.50  691.60  718.0 


2018-01-02  703.85  710.16  689.89  700.0 


2018-01-03  715.86  721.40  699.74  701.5 


2018-01-04  737.07  743.50  719.33  721.4 


2.查看后几条数据: 


price.tail() 






             close    high     low    open 


      2018-01-19  750.18  758.90  739.02  752.90 


      2018-01-22  773.64  774.00  751.81  751.81 


      2018-01-23  773.78  780.00  768.60  777.81 


      2018-01-24  764.46  776.46  758.60  776.44 


      2018-01-25  769.16  776.00  751.00  761.00 


3.查看 DataFrame  的索引 


price.index 






DatetimeIndex(['2017-12-28', '2017-12-29', '2018-01-02', '2018-01-03', 


               '2018-01-04', '2018-01-05', '2018-01-08', '2018-01-09', 


               '2018-01-10', '2018-01-11', '2018-01-12', '2018-01-15', 


               '2018-01-16', '2018-01-17', '2018-01-18', '2018-01-19', 


               '2018-01-22', '2018-01-23', '2018-01-24', '2018-01-25'], 


              dtype='datetime64[ns]', freq=None) 


4.查看 DataFrame  的列名 


price.columns 






Index(['close', 'high', 'low', 'open'], dtype='object') 




----------------------- Page 53-----------------------


5.查看 DataFrame  的值 


price.values 






array([[ 718.69,  719.9 ,  671.32,  687.  ], 


       [ 697.49,  726.5 ,  691.6 ,  718.  ], 


       [ 703.85,  710.16,  689.89,  700.  ], 


       [ 715.86,  721.4 ,  699.74,  701.5 ], 


       [ 737.07,  743.5 ,  719.33,  721.4 ], 


       [ 738.36,  746.03,  728.22,  741.  ], 


       [ 752.13,  756.5 ,  735.02,  735.02], 


       [ 782.52,  783.  ,  752.21,  752.21], 


       [ 785.71,  788.88,  773.48,  785.  ], 


       [ 774.81,  788.  ,  772.  ,  787.  ], 


       [ 788.42,  788.8 ,  767.02,  773.77], 


       [ 785.37,  799.06,  779.02,  793.46], 


       [ 772.94,  788.61,  768.  ,  780.48], 


       [ 747.93,  774.  ,  738.51,  770.  ], 


       [ 750.74,  765.  ,  744.09,  747.93], 


       [ 750.18,  758.9 ,  739.02,  752.9 ], 


       [ 773.64,  774.  ,  751.81,  751.81], 


       [ 773.78,  780.  ,  768.6 ,  777.81], 


       [ 764.46,  776.46,  758.6 ,  776.44], 


       [ 769.16,  776.  ,  751.  ,  761.  ]]) 


6.使用 describe() 函数对于数据的快速统计汇总: 


price.describe() 






            close        high         low        open 


count   20.000000   20.000000   20.000000   20.000000 


mean   754.155500  763.235000  739.924000  750.686500 


std     28.005539   26.794003   31.251968   31.581411 


min    697.490000  710.160000  671.320000  687.000000 


25%    738.037500  745.397500  725.997500  731.615000 


50%    758.295000  774.000000  747.545000  752.555000 


75%    774.037500  784.250000  767.265000  776.782500 


max    788.420000  799.060000  779.020000  793.460000 


7.对数据的转置: 


price.T 






       2017-12-28  2017-12-29  2018-01-02  2018-01-03  2018-01-04  2018-01-05  \ 


close      718.69      697.49      703.85      715.86      737.07      738.36    


high       719.90      726.50      710.16      721.40      743.50      746.03    


low        671.32      691.60      689.89      699.74      719.33      728.22    


open       687.00      718.00      700.00      701.50      721.40      741.00    






       2018-01-08  2018-01-09  2018-01-10  2018-01-11  2018-01-12  2018-01-15  \ 


close      752.13      782.52      785.71      774.81      788.42      785.37    


high       756.50      783.00      788.88      788.00      788.80      799.06    


low        735.02      752.21      773.48      772.00      767.02      779.02    


open       735.02      752.21      785.00      787.00      773.77      793.46    




----------------------- Page 54-----------------------


       2018-01-16  2018-01-17  2018-01-18  2018-01-19  2018-01-22  2018-01-23  \ 


close      772.94      747.93      750.74      750.18      773.64      773.78    


high       788.61      774.00      765.00      758.90      774.00      780.00    


low        768.00      738.51      744.09      739.02      751.81      768.60    


open       780.48      770.00      747.93      752.90      751.81      777.81    






       2018-01-24  2018-01-25   


close      764.46      769.16   


high       776.46      776.00   


low        758.60      751.00   


open       776.44      761.00   






8.按列对 DataFrame 进行排序 


print(price.sort_values(by='open' , ascending=False)) 






             close    high     low    open 


      2018-01-15  785.37  799.06  779.02  793.46 


      2018-01-11  774.81  788.00  772.00  787.00 


      2018-01-10  785.71  788.88  773.48  785.00 


      2018-01-16  772.94  788.61  768.00  780.48 


      2018-01-23  773.78  780.00  768.60  777.81 


      2018-01-24  764.46  776.46  758.60  776.44 


      2018-01-12  788.42  788.80  767.02  773.77 


      2018-01-17  747.93  774.00  738.51  770.00 


      2018-01-25  769.16  776.00  751.00  761.00 


      2018-01-19  750.18  758.90  739.02  752.90 


      2018-01-09  782.52  783.00  752.21  752.21 


      2018-01-22  773.64  774.00  751.81  751.81 


      2018-01-18  750.74  765.00  744.09  747.93 


      2018-01-05  738.36  746.03  728.22  741.00 


      2018-01-08  752.13  756.50  735.02  735.02 


      2018-01-04  737.07  743.50  719.33  721.40 


      2017-12-29  697.49  726.50  691.60  718.00 


      2018-01-03  715.86  721.40  699.74  701.50 


      2018-01-02  703.85  710.16  689.89  700.00 


      2017-12-28  718.69  719.90  671.32  687.00 


    注意:sort_values 函数内置参数有by 和 ascending,by 参数是排序指定列,ascending 是 


排序顺序,False 是从大到小,True 是从小到大。 






三、选择数据 






    依旧采用上个小节案例,继续讲述选择数据的八项基本操作。 






1.选择一列数据,选取开盘价这列数据: 


price['open'] 






2017-12-28    687.00 


2017-12-29    718.00 


2018-01-02    700.00 


2018-01-03    701.50 




----------------------- Page 55-----------------------


   2018-01-04    721.40 


   2018-01-05    741.00 


   2018-01-08    735.02 


   2018-01-09    752.21 


   2018-01-10    785.00 


   2018-01-11    787.00 


   2018-01-12    773.77 


   2018-01-15    793.46 


   2018-01-16    780.48 


   2018-01-17    770.00 


   2018-01-18    747.93 


   2018-01-19    752.90 


   2018-01-22    751.81 


   2018-01-23    777.81 


   2018-01-24    776.44 


   2018-01-25    761.00 


Name: open, dtype: float64 


    同学们动手试试price.open~ 


    它与price['open']是等效的! 






2.选择多列数据: 


price[['open','close']] 






              open   close 


    2017-12-28  687.00  718.69 


    2017-12-29  718.00  697.49 


    2018-01-02  700.00  703.85 


    2018-01-03  701.50  715.86 


    2018-01-04  721.40  737.07 


    2018-01-05  741.00  738.36 


    2018-01-08  735.02  752.13 


    2018-01-09  752.21  782.52 


    2018-01-10  785.00  785.71 


    2018-01-11  787.00  774.81 


    2018-01-12  773.77  788.42 


    2018-01-15  793.46  785.37 


    2018-01-16  780.48  772.94 


    2018-01-17  770.00  747.93 


    2018-01-18  747.93  750.74 


    2018-01-19  752.90  750.18 


    2018-01-22  751.81  773.64 


    2018-01-23  777.81  773.78 


    2018-01-24  776.44  764.46 


    2018-01-25  761.00  769.16 


    注意:price[['open','close']] 中['open','close']是一个由两个字符串 (列名)组成的列表,会 


 自动对应到整个 DataFrame 表结构中,获取到相应的数据。 


    同学们试试price['open','close'] ,看看能不能获取到数据~ 




----------------------- Page 56-----------------------


3.选择多行: 


price[0:3] 






             close    high     low   open 


2017-12-28  718.69  719.90  671.32  687.0 


2017-12-29  697.49  726.50  691.60  718.0 


2018-01-02  703.85  710.16  689.89  700.0 


4.按index 选取多行: 


price['2018-01-24':'2018-01-25'] 






             close    high    low    open 


2018-01-24  764.46  776.46  758.6  776.44 


2018-01-25  769.16  776.00  751.0  761.00 


5.使用标签选取数据: 


    price.loc[行标签,列标签] 


    price.loc['a':'b'] #选取 ab 两行数据 


    price.loc[:,'open'] #选取 open 列的数据 


    price.loc  的第一个参数是行标签,第二个参数为列标签,两个参数既可以是列表也可以 


是单个字符,如果两个参数都为列表则返回的是 DataFrame ,否则,则为 Series 。 


price.loc['2018-01-24','open'] 






776.44000000000005 






price.loc['2018-01-24':'2018-01-25'] 






             close    high    low    open 


2018-01-24  764.46  776.46  758.6  776.44 


2018-01-25  769.16  776.00  751.0  761.00 






price.loc[:, 'open'] 






  2017-12-28    687.00 


  2017-12-29    718.00 


  2018-01-02    700.00 


  2018-01-03    701.50 


  2018-01-04    721.40 


  2018-01-05    741.00 


  2018-01-08    735.02 


  2018-01-09    752.21 


  2018-01-10    785.00 


  2018-01-11    787.00 


  2018-01-12    773.77 


  2018-01-15    793.46 


  2018-01-16    780.48 


  2018-01-17    770.00 


  2018-01-18    747.93 


  2018-01-19    752.90 


  2018-01-22    751.81 


  2018-01-23    777.81 


  2018-01-24    776.44 


  2018-01-25    761.00 




----------------------- Page 57-----------------------


Name: open, dtype: float64 






price.loc['2018-01-24':'2018-01-25','open'] 






 2018-01-24    776.44 


 2018-01-25    761.00 


Name: open, dtype: float64 


6..使用位置选取数据: 


    price.iloc[行位置,列位置] 


    price.iloc[1,1] #选取第二行,第二列的值,返回的为单个值 


    price.iloc[[0,2],:] #选取第一行及第三行的数据 


    price.iloc[0:2,:] #选取第一行到第三行 (不包含)的数据 


    price.iloc[:,1] #选取所有记录的第二列的值,返回的为一个Series 


    price.iloc[1,:] #选取第一行数据,返回的为一个Series 


price.iloc[1,1] # 选取第二行,第二列的值,返回的为单个值 






726.5 






price.iloc[[0,2],:] # 选取第一行及第三行的数据 






             close    high     low   open 


2017-12-28  718.69  719.90  671.32  687.0 


2018-01-02  703.85  710.16  689.89  700.0 






price.iloc[0:2,:] # 选取第一行到第三行 (不包含)的数据 






             close   high     low   open 


2017-12-28  718.69  719.9  671.32  687.0 


2017-12-29  697.49  726.5  691.60  718.0 






price.iloc[:,1] # 选取所有记录的第一列的值,返回的为一个Series 






 2017-12-28    719.90 


 2017-12-29    726.50 


 2018-01-02    710.16 


 2018-01-03    721.40 


 2018-01-04    743.50 


 2018-01-05    746.03 


 2018-01-08    756.50 


 2018-01-09    783.00 


 2018-01-10    788.88 


 2018-01-11    788.00 


 2018-01-12    788.80 


 2018-01-15    799.06 


 2018-01-16    788.61 


 2018-01-17    774.00 


 2018-01-18    765.00 


 2018-01-19    758.90 


 2018-01-22    774.00 


 2018-01-23    780.00 


 2018-01-24    776.46 




----------------------- Page 58-----------------------


2018-01-25    776.00 


Name: high, dtype: float64 






price.iloc[1,:] # 选取第一行数据,返回的为一个Series 






close    697.49 


high     726.50 


low      691.60 


open     718.00 


Name: 2017-12-29 00:00:00, dtype: float64 


                      


7.更广义的切片方式是使用.ix,它自动根据给到的索引类型判断是使用位置还是标签进行切 


片 


    price.ix[1,1] 


    price.ix['a':'b'] 


price.ix[1,1] 






726.5 






price.ix['2018-01-24':'2018-01-25'] 






             close    high    low    open 


2018-01-24  764.46  776.46  758.6  776.44 


2018-01-25  769.16  776.00  751.0  761.00 






price.ix['2018-01-24','open'] 






776.44 






price.ix[1,'open'] 






718.0 






price.ix['2018-01-24',0] 






764.46 


8.通过逻辑指针进行数据切片: 






    price[逻辑条件] 


    price[price.one >= 2] #单个逻辑条件 


    price[(price.one >=1 ) & (df.one < 3) ] # 多个逻辑条件组合 






筛选出 open 大于 750 的数据 


price[price.open > 750] 






             close    high     low    open 


2018-01-09  782.52  783.00  752.21  752.21 


2018-01-10  785.71  788.88  773.48  785.00 


2018-01-11  774.81  788.00  772.00  787.00 


2018-01-12  788.42  788.80  767.02  773.77 


2018-01-15  785.37  799.06  779.02  793.46 




----------------------- Page 59-----------------------


 2018-01-16  772.94  788.61  768.00  780.48 


 2018-01-17  747.93  774.00  738.51  770.00 


 2018-01-19  750.18  758.90  739.02  752.90 


 2018-01-22  773.64  774.00  751.81  751.81 


 2018-01-23  773.78  780.00  768.60  777.81 


 2018-01-24  764.46  776.46  758.60  776.44 


 2018-01-25  769.16  776.00  751.00  761.00 


筛选出 open 大于 750  的数据,并且 close 小于 770  的数据 


price[(price.open > 750) & (price.close < 770)] 






             close    high     low    open 


 2018-01-17  747.93  774.00  738.51  770.00 


 2018-01-19  750.18  758.90  739.02  752.90 


 2018-01-24  764.46  776.46  758.60  776.44 


 2018-01-25  769.16  776.00  751.00  761.00 


使用 条件过来更改数据。 


price[price>780] 






             close    high  low    open 


2017-12-28     NaN     NaN  NaN     NaN 


2017-12-29     NaN     NaN  NaN     NaN 


2018-01-02     NaN     NaN  NaN     NaN 


2018-01-03     NaN     NaN  NaN     NaN 


2018-01-04     NaN     NaN  NaN     NaN 


2018-01-05     NaN     NaN  NaN     NaN 


2018-01-08     NaN     NaN  NaN     NaN 


2018-01-09  782.52  783.00  NaN     NaN 


2018-01-10  785.71  788.88  NaN  785.00 


2018-01-11     NaN  788.00  NaN  787.00 


2018-01-12  788.42  788.80  NaN     NaN 


2018-01-15  785.37  799.06  NaN  793.46 


2018-01-16     NaN  788.61  NaN  780.48 


2018-01-17     NaN     NaN  NaN     NaN 


2018-01-18     NaN     NaN  NaN     NaN 


2018-01-19     NaN     NaN  NaN     NaN 


2018-01-22     NaN     NaN  NaN     NaN 


2018-01-23     NaN     NaN  NaN     NaN 


2018-01-24     NaN     NaN  NaN     NaN 


2018-01-25     NaN     NaN  NaN     NaN 


观察可以发现,price  中小于等于 780  的数都变为 NaN 。 




----------------------- Page 60-----------------------


我们还可以把大于 780  的数赋值为 1. 


price[price > 780] = 1 






             close    high     low    open 


      2017-12-28  718.69  719.90  671.32  687.00 


      2017-12-29  697.49  726.50  691.60  718.00 


      2018-01-02  703.85  710.16  689.89  700.00 


      2018-01-03  715.86  721.40  699.74  701.50 


      2018-01-04  737.07  743.50  719.33  721.40 


      2018-01-05  738.36  746.03  728.22  741.00 


      2018-01-08  752.13  756.50  735.02  735.02 


2018-01-09    1.00    1.00  752.21  752.21 


2018-01-10    1.00    1.00  773.48    1.00 


2018-01-11  774.81    1.00  772.00    1.00 


2018-01-12    1.00    1.00  767.02  773.77 


2018-01-15    1.00    1.00  779.02    1.00 


2018-01-16  772.94    1.00  768.00    1.00 


      2018-01-17  747.93  774.00  738.51  770.00 


      2018-01-18  750.74  765.00  744.09  747.93 


      2018-01-19  750.18  758.90  739.02  752.90 


      2018-01-22  773.64  774.00  751.81  751.81 


      2018-01-23  773.78  780.00  768.60  777.81 


      2018-01-24  764.46  776.46  758.60  776.44 


      2018-01-25  769.16  776.00  751.00  761.00 


使用 isin()方法来过滤在指定列中的数据,案例延续上面赋值后的price 


# 选取 high 列中数为 1 和 774.00 的数。 


price[price['high'].isin([1,774.00])] 






             close   high     low    open 


2018-01-09    1.00    1.0  752.21  752.21 


2018-01-10    1.00    1.0  773.48    1.00 


2018-01-11  774.81    1.0  772.00    1.00 


2018-01-12    1.00    1.0  767.02  773.77 


2018-01-15    1.00    1.0  779.02    1.00 


2018-01-16  772.94    1.0  768.00    1.00 


2018-01-17  747.93  774.0  738.51  770.00 


2018-01-22  773.64  774.0  751.81  751.81 






四、 Panel 






    MindGo 量化交易平台的 get_price 函数,如果是获取多支股票数据, 则返回pandas.Panel 


对象。pane 其实就是一张一张DataFrame 整合。 






# 获取贵州茅台,招商银行,中信证券这三只股票近10 个工作日的开盘价、最高价、最低价、 


收盘价,获取格式即为DataFrame 


price= get_price(['600519.SH','600036.SH','600030.SH'], None, '20180125', '1d', ['open', 'high',  


'low', 'close'], False, 'pre', 20, is_panel=1) 


print(price) 






<class 'pandas.core.panel.Panel'> 


Dimensions: 4 (items) x 20 (major_axis) x 3 (minor_axis) 




----------------------- Page 61-----------------------


Items axis: close to open 


Major_axis axis: 2017-12-28 00:00:00 to 2018-01-25 00:00:00 


Minor_axis axis: 600030.SH to 600519.SH 


    注意:现在这个price 不是一张DataFrame ,而是三个股票的DataFrame 了,那么我们需 


要通过股票代码、数据字段下标,来分别获取多张DataFrame ,之后的操作就是操作单张 


DataFrame 了。 


price['close']#获取三个股票的收盘价,注意获取后是个DataFrame 






            600030.SH  600036.SH  600519.SH 


2017-12-28      18.12      28.63     718.69 


2017-12-29      18.10      29.02     697.49 


2018-01-02      18.44      29.62     703.85 


2018-01-03      18.61      29.97     715.86 


2018-01-04      18.67      29.65     737.07 


2018-01-05      18.88      30.10     738.36 


2018-01-08      19.54      29.47     752.13 


2018-01-09      19.44      29.77     782.52 


2018-01-10      19.61      30.53     785.71 


2018-01-11      19.28      30.92     774.81 


2018-01-12      19.33      31.51     788.42 


2018-01-15      19.45      31.94     785.37 


2018-01-16      20.25      31.89     772.94 


2018-01-17      20.94      31.69     747.93 


2018-01-18      21.41      32.32     750.74 


2018-01-19      21.29      32.46     750.18 


2018-01-22      21.20      33.08     773.64 


2018-01-23      21.21      34.05     773.78 


2018-01-24      22.92      33.85     764.46 


2018-01-25      22.33      33.41     769.16 






price['open']#获取开盘价股票数据,注意获取的还是DataFrame 






        600030.SH  600036.SH  600519.SH 


2017-12-28      18.06      28.75     687.00 


2017-12-29      18.12      28.63     718.00 


2018-01-02      18.13      29.02     700.00 


2018-01-03      18.36      29.74     701.50 


2018-01-04      18.64      30.28     721.40 


2018-01-05      18.68      29.87     741.00 


2018-01-08      19.00      29.92     735.02 


2018-01-09      19.55      29.52     752.21 


2018-01-10      19.47      29.66     785.00 


2018-01-11      19.46      30.52     787.00 


2018-01-12      19.25      31.12     773.77 


2018-01-15      19.25      31.48     793.46 


2018-01-16      19.26      31.80     780.48 


2018-01-17      20.50      32.10     770.00 


2018-01-18      21.15      32.10     747.93 


2018-01-19      21.36      32.66     752.90 


2018-01-22      21.10      32.18     751.81 


2018-01-23      21.37      33.20     777.81 




----------------------- Page 62-----------------------


2018-01-24      21.40      34.25     776.44 


2018-01-25      22.50      34.01     761.00 






price['2018-01-11']#获取2018-01-11  日期的三个股票的数据 






KeyError: '2018-01-11'  






    注意这是不可行的,思考下为什么? 




----------------------- Page 63-----------------------


第七节:pandas 进阶 






    本节为pandas 进阶内容,核心还是DataFrame 数据处理,注意包括缺失数据处理、函数 


的应用和映射、数据规整等。 


    开始之前首先导入库:numpy 和pandas 


import pandas as pd 


import numpy as np  






一、缺失数据处理 






    还是获取MindGo 平台的数据来演示: 


# 获取招商银行近10 个工作日的开盘价、最高价、最低价、收盘价。并将部分数据赋值为 


NAN ,假设为缺失部分。 


price= get_price('600036.SH', None, '20180125', '1d', ['open', 'high', 'low', 'close'], False, 'pre', 10,  


is_panel=1) 


price[price > 34] = np.nan 


print(price) 






            close   high    low   open 


  2018-01-12  31.51  31.58  31.02  31.12 


  2018-01-15  31.94  32.40  31.30  31.48 


  2018-01-16  31.89  32.28  31.54  31.80 


  2018-01-17  31.69  33.11  31.50  32.10 


  2018-01-18  32.32  32.75  32.10  32.10 


  2018-01-19  32.46  33.35  32.21  32.66 


  2018-01-22  33.08  33.64  32.15  32.18 


2018-01-23    NaN    NaN  33.20  33.20 


2018-01-24  33.85    NaN  33.45    NaN 


2018-01-25  33.41    NaN  32.90    NaN 


1.去掉包含缺失值的行 


price.dropna() 






            close   high    low   open 


  2018-01-12  31.51  31.58  31.02  31.12 


  2018-01-15  31.94  32.40  31.30  31.48 


  2018-01-16  31.89  32.28  31.54  31.80 


  2018-01-17  31.69  33.11  31.50  32.10 


  2018-01-18  32.32  32.75  32.10  32.10 


  2018-01-19  32.46  33.35  32.21  32.66 


  2018-01-22  33.08  33.64  32.15  32.18 


2.对缺失值进行填充为 30 


price.fillna(value=30) 






            close   high    low   open 


  2018-01-12  31.51  31.58  31.02  31.12 


  2018-01-15  31.94  32.40  31.30  31.48 


  2018-01-16  31.89  32.28  31.54  31.80 


  2018-01-17  31.69  33.11  31.50  32.10 


  2018-01-18  32.32  32.75  32.10  32.10 


  2018-01-19  32.46  33.35  32.21  32.66 




----------------------- Page 64-----------------------


     2018-01-22  33.08  33.64  32.15  32.18 


     2018-01-23  30.00  30.00  33.20  33.20 


     2018-01-24  33.85  30.00  33.45  30.00 


     2018-01-25  33.41  30.00  32.90  30.00 


3.判断数据是否为nan 


pd.isnull(price) 






            close   high    low   open 


2018-01-12  False  False  False  False 


2018-01-15  False  False  False  False 


2018-01-16  False  False  False  False 


2018-01-17  False  False  False  False 


2018-01-18  False  False  False  False 


2018-01-19  False  False  False  False 


2018-01-22  False  False  False  False 


2018-01-23   True   True  False  False 


2018-01-24  False   True  False   True 


2018-01-25  False   True  False   True 






二、函数的应用和映射 






    再次获取MindGo 平台的数据来演示: 


# 获取招商银行近10 个工作日的开盘价、最高价、最低价、收盘价。 


price= get_price('600036.SH', None, '20180125', '1d', ['open', 'high', 'low', 'close'], False, 'pre', 10,  


is_panel=1) 


print(price) 


            close   high    low   open 


     2018-01-12  31.51  31.58  31.02  31.12 


     2018-01-15  31.94  32.40  31.30  31.48 


     2018-01-16  31.89  32.28  31.54  31.80 


     2018-01-17  31.69  33.11  31.50  32.10 


     2018-01-18  32.32  32.75  32.10  32.10 


     2018-01-19  32.46  33.35  32.21  32.66 


     2018-01-22  33.08  33.64  32.15  32.18 


     2018-01-23  34.05  34.17  33.20  33.20 


     2018-01-24  33.85  35.35  33.45  34.25 


     2018-01-25  33.41  34.02  32.90  34.01 


1.列计算平均值 


price.mean() 






close    32.620 


high     33.265 


low      32.137 


open     32.490 


dtype: float64 


2.行计算平均值 


price.mean(1) 






2018-01-12    31.3075 


2018-01-15    31.7800 


2018-01-16    31.8775 




----------------------- Page 65-----------------------


 2018-01-17    32.1000 


 2018-01-18    32.3175 


 2018-01-19    32.6700 


 2018-01-22    32.7625 


 2018-01-23    33.6550 


 2018-01-24    34.2250 


 2018-01-25    33.5850 


dtype: float64 


如果你担心你求均值时受到缺失值的影响,你可以: 


price.mean(axis = 1,skipna = True) # skipna 参数默认是 True 表示排除缺失值  axis=1 是按行  


axis=0 是按列 






 2018-01-12    31.3075 


 2018-01-15    31.7800 


 2018-01-16    31.8775 


 2018-01-17    32.1000 


 2018-01-18    32.3175 


 2018-01-19    32.6700 


 2018-01-22    32.7625 


 2018-01-23    33.6550 


 2018-01-24    34.2250 


 2018-01-25    33.5850 


dtype: float64 






三、数据规整 






    Pandas 提供了大量的方法能够轻松的对Series,DataFrame 和 Panel 对象进行各种符合各 


种逻辑关系的合并操作,主要介绍三个常用操作。 






 操作方式                                             释义 






 concat                                           可以沿一条轴将多个对象堆叠到一起。 






 append                                           将一行连接到一个DataFrame 上 






 duplicated                                       移除重复数据 






1.concat 






首先我们分别获取两个 DataFrame 。 


# 获取招商银行20180125  日的前5 个工作日的开盘价、最高价、最低价、收盘价。 


price1= get_price('600036.SH', None, '20180125', '1d', ['open', 'high', 'low', 'close'], False, 'pre', 5,  


is_panel=1) 


print(price1) 






            close   high    low   open 


2018-01-19  32.46  33.35  32.21  32.66 


2018-01-22  33.08  33.64  32.15  32.18 


2018-01-23  34.05  34.17  33.20  33.20 


2018-01-24  33.85  35.35  33.45  34.25 


2018-01-25  33.41  34.02  32.90  34.01 




----------------------- Page 66-----------------------


# 获取招商银行20170125  日的前5 个工作日的开盘价、最高价、最低价、收盘价。 


price2= get_price('600036.SH', None, '20170125', '1d', ['open', 'high', 'low', 'close'], False, 'pre', 5,  


is_panel=1) 


print(price2) 






            close   high    low   open 


     2017-01-19  18.52  18.74  18.51  18.55 


     2017-01-20  18.59  18.65  18.47  18.54 


     2017-01-23  18.50  18.76  18.41  18.68 


     2017-01-24  18.87  18.88  18.50  18.59 


     2017-01-25  18.88  18.95  18.68  18.81 


纵向拼接(默认) : 


pd.concat([price1,price2],axis=0) 






            close   high    low   open 


     2018-01-19  32.46  33.35  32.21  32.66 


     2018-01-22  33.08  33.64  32.15  32.18 


     2018-01-23  34.05  34.17  33.20  33.20 


     2018-01-24  33.85  35.35  33.45  34.25 


     2018-01-25  33.41  34.02  32.90  34.01 


     2017-01-19  18.52  18.74  18.51  18.55 


     2017-01-20  18.59  18.65  18.47  18.54 


     2017-01-23  18.50  18.76  18.41  18.68 


     2017-01-24  18.87  18.88  18.50  18.59 


     2017-01-25  18.88  18.95  18.68  18.81 


横向拼接,index 对不上的会用 NaN 填充: 


pd.concat([price1,price2],axis=1) 






            close   high    low   open  close   high    low   open 


2017-01-19    NaN    NaN    NaN    NaN  18.52  18.74  18.51  18.55 


2017-01-20    NaN    NaN    NaN    NaN  18.59  18.65  18.47  18.54 


2017-01-23    NaN    NaN    NaN    NaN  18.50  18.76  18.41  18.68 


2017-01-24    NaN    NaN    NaN    NaN  18.87  18.88  18.50  18.59 


2017-01-25    NaN    NaN    NaN    NaN  18.88  18.95  18.68  18.81 


2018-01-19  32.46  33.35  32.21  32.66    NaN    NaN    NaN    NaN 


2018-01-22  33.08  33.64  32.15  32.18    NaN    NaN    NaN    NaN 


2018-01-23  34.05  34.17  33.20  33.20    NaN    NaN    NaN    NaN 


2018-01-24  33.85  35.35  33.45  34.25    NaN    NaN    NaN    NaN 


2018-01-25  33.41  34.02  32.90  34.01    NaN    NaN    NaN    NaN 






2.append 






首先获取数据 


# 获取招商银行20180125  日的前5 个工作日的开盘价、最高价、最低价、收盘价。 


price= get_price('600036.SH', None, '20180125', '1d', ['open', 'high', 'low', 'close'], False, 'pre', 5,  


is_panel=1) 


print(price) 






            close   high    low   open 


     2018-01-19  32.46  33.35  32.21  32.66 


     2018-01-22  33.08  33.64  32.15  32.18 




----------------------- Page 67-----------------------


    2018-01-23  34.05  34.17  33.20  33.20 


    2018-01-24  33.85  35.35  33.45  34.25 


    2018-01-25  33.41  34.02  32.90  34.01 






s = price.iloc[0] 


print(s) 






close    32.46 


high     33.35 


low      32.21 


open     32.66 


Name: 2018-01-19 00:00:00, dtype: float64 






price.append(s, ignore_index=False) # ignore_index=False 表示索引不变 






            close   high    low   open 


    2018-01-19  32.46  33.35  32.21  32.66 


    2018-01-22  33.08  33.64  32.15  32.18 


    2018-01-23  34.05  34.17  33.20  33.20 


    2018-01-24  33.85  35.35  33.45  34.25 


    2018-01-25  33.41  34.02  32.90  34.01 


    2018-01-19  32.46  33.35  32.21  32.66 






price.append(s, ignore_index=True) # ignore_index=True 表示索引重置 






   close   high    low   open 


0  32.46  33.35  32.21  32.66 


1  33.08  33.64  32.15  32.18 


2  34.05  34.17  33.20  33.20 


3  33.85  35.35  33.45  34.25 


4  33.41  34.02  32.90  34.01 


5  32.46  33.35  32.21  32.66 






3.移除重复数据 duplicated 






延续append 示例 






price2=price.append(s, ignore_index=False) # ignore_index=False 表示索引不变 






            close   high    low   open 


    2018-01-19  32.46  33.35  32.21  32.66 


    2018-01-22  33.08  33.64  32.15  32.18 


    2018-01-23  34.05  34.17  33.20  33.20 


    2018-01-24  33.85  35.35  33.45  34.25 


    2018-01-25  33.41  34.02  32.90  34.01 


    2018-01-19  32.46  33.35  32.21  32.66 




----------------------- Page 68-----------------------


查看重复数据: 


price2.duplicated() 






2018-01-19    False 


2018-01-22    False 


2018-01-23    False 


2018-01-24    False 


2018-01-25    False 


2018-01-19     True 


dtype: bool 


移除重复数据: 


price2.drop_duplicates() 






            close   high    low   open 


 2018-01-19  32.46  33.35  32.21  32.66 


 2018-01-22  33.08  33.64  32.15  32.18 


 2018-01-23  34.05  34.17  33.20  33.20 


 2018-01-24  33.85  35.35  33.45  34.25 


 2018-01-25  33.41  34.02  32.90  34.01 


可以看到'2018-01-19' 的重复行被删除了 




----------------------- Page 69-----------------------