第三章:Python 编程

第一节: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———————–


版权声明:本文为wuyusheng314原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。