第一节: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]
6
b=(1,3,6,10)
b[2]
6
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')
1
删除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
4
----------------------- Page 38-----------------------
5
6
7
8
虽然while 后面的条件是a<10,即a 小于 10 的时候一直执行,但是 if 条件中规定了 a 为
8 时就break 掉,因此,输出只能输到8。
三、for 语句
可以遍历一个序列/字典等。
a=[1,2,3,4,5]
for i in a:
print(i)
1
2
3
4
5
----------------------- 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])
6
----------------------- 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)
6
sum_my(1, 3, 5, 7)
16
定义可变参数和定义 list 或 tuple 参数相比,仅仅在参数前面加了一个 * 号。在函数内
部,参数 numbers 接收到的是一个 tuple ,因此,函数代码完全不变。但是,调用该函数时,
可以传入任意个参数,包括 0 个参数:
sum_my()
0
如果已经有一个 list 或者 tuple ,要调用一个可变参数怎么办? Python 允许你在 list 或
tuple 前面加一个 * 号,把 list 或 tuple 的元素变成可变参数传进去,可以这样做:
number = [1, 2, 3]
sum_my(*number)
6
这种写法相当有用,而且很常见。
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
2
查看数组的维数使用 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()
3
9.a 中最小的元素
a.min()
1
10.a 的和
a.sum()
6
----------------------- 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-----------------------