棕榈学院Python课程回顾——K线图绘制

棕榈学院Python课程回顾(Day 1-2)

棕榈学院的这个课程总体上来看还是相当不错的, 我花了很多的精力,也学习了很多的技巧,在这里整理一下。我之前学过的因为没有整理,导致之后要用的时候又找不到,所以还是很有必要的。

环境配置

​ 在Python的编写之前,都会讲环境的搭建,我个人比较喜欢用Sublime text 3,这个编译器简单流畅,而且颜值还不错;但是最近比较流行的就是jupyter notebook,这个notebook是基于ipython的一个环境吧,可以像Rstudio一样一行一行的跑代码。搭建的环境网上都有很多,我就把自己用到的po上来了,以后要是换了新电脑还可以根据这个重新配置hhh。

Sublime text 3

​ 这里需要先说一下,python中安装模块,参考(http://shujuren.org/article/752.html)。

​ Sublime text 3编译器官网直接下载,在Sublime text 3里面跑python代码,需要稍微设置一下(http://shujuren.org/article/723.html),酱紫写完代码就可以ctrl+B直接运行。

Sublime text 3的自动换行设置,参考(https://blog.csdn.net/liu857279611/article/details/51512624)。

​ 就这么多吧,真的很好用、很好看,良心推荐!

jupyter notebook

​ 这个东西其实并不一定需要anaconda,自己pip安装一下jupyter就可以了,安装教程参考(https://www.jb51.net/article/135172.htm),然后进入python的文件夹,比如我的都安装在 ‘D:\Python\Scripts’ 这里,打开的时候就直接win+R,cd D:\Python\Scripts,输入jupyter notebook,在浏览器中就可以直接弹出notebook了,很简单。

​ 如果要更改notebook的工作目录,可以参考这个链接(https://www.jianshu.com/p/3360b4b79ee1)。

​ 然后因为,jupyter notebook的配色真的丑,所以需要改一下主题(就是皮肤),参考这里(https://blog.csdn.net/qq_30565883/article/details/79444750);改完这个皮肤之后会发现Jupyter notebook 输出部分显示不全的问题,参考(https://blog.csdn.net/dlh_sycamore/article/details/83041402);可能代码部分也看不完全,推荐设置自动换行,参考(https://cloud.tencent.com/developer/article/1175518)。

扫描二维码关注公众号,回复: 4122201 查看本文章

​ 环境的配置我使用到的应该就是这些了,如果还有漏掉的话就之后再补充了。

Day 1 文件读取

​ 第一天的知识点,除了环境的配置,就是文件的读取了。下面展示一些笔记:

file = open("data.txt","r")
# 这里的r,表示只读取文件,如果是w表示写入文件
i=1
for line in file:
	print("read line", i)
	i = i+1
	print(line)
# 可以将文件一行一行的打印出来
######################################
file = open('hello.txt', "w")
file.write('hello world\n')
file.write("it is a sunny day")
file.close()

file = open("hello.txt","r")
for line in file:
	print(line)
# 这个是写文件了,写完要加上一个file.close(),关闭掉。

#######################################
# 当然也可以打开其他格式的文档
file = open('data.csv', 'r')
# 但是.csv\.xlsx这些文件我们一般都是用pandas打开的。
import pandas as pd
file = pd.read_csv('data.csv', index_col = 0)
file = pd.read_excel('data.xlsx')
file = pd.read_table('data.txt', sep=',', index_col = 0)
# index_col = 0 避免了系统给补充一个index
# 储存文件
df.to_excel('data.xlsx')

#######################################
# 读取复杂的data
df = pd.read_table('data1.txt', sep = ',', skiprows = [0,1,2,3], header = None, names = ['n1', 'n2', 'n3', 'n4', 'message'], index_col = ['message'], nrow = 5)
# skiprow 跳过几行不读
# header = None 每一列的名字不在数据中
# names 给每一列命名
# nrow = 5 表示5个一行读

Day 2 数据类型

基本数据类型

  • integer, float, string, True/False
  • type() 可以查看数据类型

给变量赋值

x = 1
x,y,z = 1,4,2
x,y = [1,2]
x,y ='12'

表判断的时候要用 “==”双等号

bbb = 1 # 这里是赋值
bbb != 3 
bbb == 1
# 后买你俩一个判断不是、一个判断是

数据类型的转化

str()
float()
int()

基本运算

+, -, *, /, **,
x += 1 # 就是指 x = x + 1
round(2.544, 0) # 约到几位小数
int(2.553) # 直接取整
abs(-5) # 求绝对值

import math
math.log10(2) # log以10为底数,2为对数
math.log(8,2) # log以2为底数,8为对数
math.exp(2) # e^2
math.sqrt(2) # 开根号2
math.pi
math.e
math.sin()
math.modf(2.545) # 小数整数分开(自己试)

Day 3 数据结构

​ 这一讲就是数据的结构了。

列表list

把多个不同类型的变量放在一起

L = []
x = [1,2,3,'hi',2,4,5,6,'ddd',True]

# 查看列表的长度
len(x) 

# 列表的索引都是从0开始的, 所以第一个数是0,以此类推
x[0] 

# 直接赋值
x[4] = 7

# 切片
x[3:5] # 这个输出的就是x[3],x[4]。x[5]就不会输出
x[:-2] # 删除列表的后两列

# 排序
sorted(x)
sorted(x, reverse = True)
x.sort()
# 这里需要注意的是:
# sorted()不只是针对list,参数reverse = True/False可以调整排序方式
# .sort()只作用于列表

# 添加元素
x.extend([3,4,5])
x.append([3,4,5])
# .extend()是将3,4,5这3个元素添加进去,
# .append()则是将[3,4,5]这一个元素添加进去
# 列表之间可以直接做加法
x += [3,4,5]
x += [[3,4,5]]
# 所以加法其实可以完成 .extend()和.append()两种方式

# 插入元素
x.insert(3, 6)
# 把6插入到x[3]的位置

# 删除元素
x.remove(2)
# 只能删掉第一个2
del x[2]
# 指定删除的索引
x.pop()
# 没有指定位置的时候,直接删除最后一个元素
x.pop(2)
# 给它一个索引,就把那个索引处的元素删掉

# 记数
x.count(2)
#可以统计2这个元素在list中出现的次数

元组tuple

和list一样,但是tuple中的内容是不可以改变的;

元组的切片与索引以及排序均和 list相同

y = (1,2,3,'xxx','1',2)

字典dict

字典的索引就不是数字了,而是key,它的值就是value。

D = {}

z = {'1':'hi','sss':'2','3':[1,2],'hi':(1,2,3)}

# 查看dict的长度
len(z) 

# 用键名进行索引
z['1']
z['hi']

# 赋值
z['name'] = 3

# 查看键名和键值
z.keys()
z.values()
z.items()
# .item()可以把每组键、值按顺序跑出来,写字典循环的时候要用
for key,value in z.item:
    print('key: ', key, '\n')
    print('value: ', value, '\n')
    
# 删除字典中的键和键值,同list
  • 集合 set

类似数列,表示把多个不同类型的变量放在一起。这个没有上述3种用的多,不是很熟悉。

两点:1. 一个 Set里面的值具有唯一性; 2. 一个 Set可以是空的

S = set()
I = {'1',1,1,1,'hiahiahia'}
s = {1,2,3,4,4,4,4}
print(s)

Day 4 复合语句if, while, for, del

​ 复合语句:条件语句、循环语句、函数定义

if

x, y = 1, 2
if x > y:
    z = x + y
elif x == y:
    z = x
else:
    z = y - x
print(z)

for

x = [1,2,13,14]
for i in x:
    print(i)
    
for i in range(4):
    print(i)
   
for i in range(len(x)):
    print(x[i])

for i in range(1,10):
    if i%2 == 0:
        break
    print(i)
# break 整个循环直接中断,打印1.没了

for i in range(1,10):
    if i%2 == 0:
        pass
    print(i)
# pass 不管这一个条件语句,在循环内进行下一行操作

for i in range(1,10):
    if i%2 == 0:
        continue
    print(i)
# continue 这个循环跳过,进入下一个循环

while

i = 1
while i < 5:
    print(i)
    i += 1

def

def add(x,y):
    return(x+y)

Day 5 数据框和系列

​ pd.Series, pd.DataFrame 数据框和系列

import pandas as pd
import numpy as np
# pandas 是处理数据框和系列的包
# numpy 是一个数学的包

Series

​ Series这个东西给我的感觉就是:在DataFrame中取一列就是一个Series

s1 = pd.Series((1,2,3,4,5))
s1.values
s1.index
# 赋值和list、dict一样
s1[1] = 5
# index也可以直接赋值
s1.index = ['a','b','c','d','e']
# 也可以创建的时候就指定好index
s2 = pd.Series([1,2,3,4,5], index = ['a','b','c','d','e'])

# 切片,同list, dict
s2['a']
s2[0]

# Series之间的运算,索引重合才能计算
s3 = s1 + s2

# 查缺失值
s3.isnull()
s3.notnull()

DataFrame

​ Python中最常用的数据结构,非常好用。

# DataFrame的创建
dat1 = {'A':[1,2,3,4],'B':[3,4,5,6],'C':[4,5,6,7],'D':[11,12,13,14], index = ['x','y','z','k']}
df1 = pd.DataFrame(dat1)
# index可以直接指定

# 一个产生随机数的函数
np.random.seed(1)
np.random.randn(10,4)
# 默认应该是按照N(0,1)分布随机生成10行,4列的数据。
df2 = pd.DataFrame(np.random.randn(10,4), columns = ['A','B','C','D'], index = ['2018-01-01', '2018-01-02', '2018-01-03', '2018-01-04', '2018-01-05', '2018-01-06', '2018-01-07', '2018-01-08', '2018-01-09', '2018-01-10'])
# 随机生成了数据,columns指定了列名,index指定了索引
############################################################

# DataFrame的切片和索引
type(df2[['A']])
type(df2['A'])
# 双中括号的时候,切片出来的是DataFrame,单中括号提取出来的是Series
df2[['A','B']]
# 所以取两列,一定要用双中括号,表示这是一个DataFrame

df2['A']['2018-01-01']
df2[['A','B']]['2018-01-01':'2018-01-01']
df2.loc[['2018-01-01'],['A','B']]
df2.loc[['2018-01-01','2018-01-02'],['A','B']]
df2.iloc[[0],[0,1]]
# .iloc[]这个函数还是相当好用的。当然,双中括号还是输出DataFrame,单中括号输出Series
###########################################################

# 赋值和简单运算
df2.iloc[[0],[0,1]] = 0
df2['E'] = 3.33
df2['F'] = df2['A'] + df2['B'] - df2['C']

Day 6 数据框的合并

​ DataFrame作为最常用的数据储存模式,DATa Frame之间的操作函数

concatenate

pd.concat(objs, axis = 0, join = 'inner', join_axes = None, ignore_index = False, keys = None, levels = None, names = None, verify_integrity = False, copy = True)

函数参数很多蛤,我也不一一说明了,要用的时候查document。

df1 = pd.DataFrame({'A': ['A0','A1','A2','A3'],
					'B': ['B0','B1','B2','B3'],
					'C': ['C0','C1','C2','C3'],
					'D': ['D0','D1','D2','D3']},
					index = [0,1,2,3])
df2 = pd.DataFrame({'A': ['A4','A5','A6','A7'],
					'B': ['B4','B5','B6','B7'],
					'C': ['C4','C5','C6','C7'],
					'D': ['D4','D5','D6','D7']},
					index = [4,5,6,7])
df3 = pd.DataFrame({'A': ['A8','A9','A10','A11'],
					'B': ['B8','B9','B10','B11'],
					'C': ['C8','C9','C10','C11'],
					'D': ['D8','D9','D10','D11']},
					index = [8,9,10,11])
# df_concat()
df_concat = pd.concat([df1, df2, df3])
# 行数相加

df4 = pd.DataFrame({'B': ['B2','B3','B6','B7'],
					'D': ['D2','D3','D6','D7'],
					'F': ['F2','F3','F6','F7']},
					index = [2,3,6,7])
df_concat_axis1 = pd.concat([df1, df4], axis = 1)
# 列数相加

dff34_joininner = pd.concat([ddf3, ddf4], axis = 1, join = 'inner')
## join 默认是outer,就是所有的数据都放进来,而inner是把共有的数据放进来

dff34_joinaxes = pd.concat([ddf3, ddf4], axis = 1, join_axes = [ddf4.index])
## join_axes保留一个表格中的所有index

dff34_ignoreindex = pd.concat([ddf3, ddf4], ignore_index = True)
## ignore_index 就是忽略index

补充:.dropna()

DataFrame中针对NA值的处理一个方法。

df_concat_axis1.dropna(how = 'any')
# 一行中出现na就删掉一行
df_concat_axis1.dropna(how = 'all')
# 一行中全都是na才删

补充:显示所有行或列

pd.set_option('display.max_columns', None) 
## 显示所有列
pd.set_option('display.max_rows', None)    
## 显示所有行
pd.set_option('max_colwidth',100)          
## 设置value的显示长度为100,默认为50

merge

pd.merge(left, right, how = 'inner', on = None, left_on = None, right_on = None, left_index = false, right_index = Flase, sort = True, suffixes('_x', '_y'), copy = True, indicator = False, validate = None)

还是要用的时候查document就行。

left = pd.DataFrame({'key': ['K0','K1','K2','K3'],
					 'A'  : ['A0','A1','A2','A3'],
					 'B'  : ['B0','B1','B2','B3']})
right = pd.DataFrame({'key': ['K0','K1','K2','K3'],
					  'C'  : ['C0','C1','C2','C3'],
					  'D'  : ['D0','D1','D2','D3']})
pd.merge(left, right, on = 'key')
# 以'key'为index将两DataFrame合并
######################################################

leftname = pd.DataFrame({'firstname': ['Pool', 'House', 'Mine', 'Will'], 'location': [1,2,1,4]})
rightname = pd.DataFrame({'lastname': ['Henry', 'Jones', 'Indiana', 'Jack'], 'location': [1,2,3,5]})
namemergeinner = pd.merge(leftname, rightname, on = 'location')
## merge的默认合并方式是inner,只保留共有的index
namemergeouter = pd.merge(leftname, rightname, on = 'location', how = 'outer')
## how = 'outer'保留所有的index
namemergeleft = pd.merge(leftname, rightname, on = 'location', how = 'left')
## how = 'left'保留左边的index
namemergeright = pd.merge(leftname, rightname, on = 'location', how = 'right')
## how = 'right'保留右边的index

d1 = pd.DataFrame({'A': [1,5,9,13],
				'B': [2,6,10,14],
				'C': [3,7,11,15],
				'D': [4,8,12,16],
				'E': ['H','J','K','L']},
				index = [0,1,2,3])
d2 = pd.DataFrame({1: ['H','L','J','J'],
				2: ['S','S','S','T'],
				3: [6,2,5,3]},
				index = [0,1,2,3])
d3_1 = pd.merge(d1, d2, left_on = 'E', right_on = 1, how = 'outer')
## 指定左边依据'E'列为index,右边以1为index

join

left.join(right, on = key/keys)
# 从功能上来讲,这俩函数是相同的,上者无疑更为简介明了;但merge因为有更多参数,所以可以实现更为复杂的功能
pd.merge(left, right, left_on, right_index = True, how = 'left', sort = False)

还是那句话,要用的时候查document。

left = pd.DataFrame({'A'  : ['A0','A1','A2'],
					 'B'  : ['B0','B1','B2']},
					 index = ['K0','K1','K2'])
right = pd.DataFrame({'C'  : ['C0','C1','C2'],
					  'D'  : ['D0','D1','D2']},
					  index = ['K0','K1','K2'])
left.join(right, how = 'outer')
# .join()也有how函数

Day 7 简单画图

import matplotlib.pyplot as plt
import numpy as np
import seaborn as sns
import warnings
warnings.filterwarnings("ignore")
# 忽略warnings弹出

y1 = [102,134,154,122,143,243,355,342,276,299,241,287,260,231,100]
y2 = [244,250,245,256,234,241,230,267,266,255,248,239,233,221,227]
# 先把数据模拟好
plt.figure(figsize=(15,20)) 
plt.subplot(331)
# plt.figure构建一个画板,figure画板的大小
# 这个函数和plt.add_subplot(3,3,1)类似,就是说将画布分成3行、3列,画在第一个位置。
plt.plot(x,y)
# plt.plot()画折线图
plt.title("Weight change in 15 months")
# 主标题
plt.xlabel('Month')
# x轴
plt.ylabel('kg')
# y轴

plt.subplot(332)
plt.plot(x, y1, label = 'A')
plt.plot(x, y2, label = 'B')
# 画两条线或者多条线,都可以的
plt.legend(fontsize = 10)
# plt.legend()是设置图例的

plt.subplot(333)
plt.bar(x,y,color = '#9999ff', width = 0.5)
# plt.bar()柱状图

plt.subplot(335)
plt.scatter(x,y)
# 散点图

x = range(20)
y = x + np.random.randn(20)*1.05
plt.subplot(336)
# plt.scatter(x,y) 这个函数也可以画散点图
plt.plot(x,y,'*')
plt.plot(x,x)
# plot()里面设置了*号,表示要画散点图

plt.subplot(337)
plt.boxplot([y1,y2])
plt.xticks([1,2], ['A','B'])
# boxplot箱线图。
# xtricks([1,2],['A','B'])是对x轴上的1,2进行替换。左边填入原来的值,右边填入替换他们的值

plt.subplot(339)
gaussian_numbers = np.random.randn(1000)
plt.hist(gaussian_numbers, 30, color = 'navy', alpha = 0.5)
plt.tight_layout() #设置默认的间距
# plt.hist()中的30是30根柱子,alpha是饱和度。

day7

​ 关于plt.subplot的用法,可以参考(https://blog.csdn.net/data8866/article/details/66973532)。

Day 8 Datetime

大部分的数据都会涉及到时间的处理,而时间多样而繁杂的表示方式无疑是给统一的分析和管理带来不变,所以一般的数据分析软件都会有一个专门的时间变量的类型。

df2 = pd.DataFrame(np.random.randn(10,4), columns = ['A','B','C','D'], index = ['2018-01-01', '2018-01-02', '2018-01-03', '2018-01-04', '2018-01-05', '2018-01-06', '2018-01-07', '2018-01-08', '2018-01-09', '2018-01-10'])
df2.index = pd.to_datetime(df2.index, format = '%Y-%m-%d')
# 这里的format是指原数据的形式

Day 9 API的调用

​ 好多的数据库要调用他们的数据需要用API来调用。这一次我们需要使用的数据库是alpha avantage (https://www.alphavantage.co/),再调用之前,我们要先去这个网页申请到自己的API。拿到一个APIkey。

import matplotlib.pyplot as plt
import seaborn as sns
import pandas as pd
import urllib.request
import json
# uellib.request是一个常用的网页调用包
# json是json这种数据储存语言的处理包

url = 'https://www.alphavantage.co/query?function='+timeseries+'&symbol='+ticker+'&interval='+interval+'&apikey='+APIkey
# 这个是网站调用的链接,在function=后面要接我们所调用数据的性质,timeseries是可以选择Intraday还是daily,symbol就是选择公司,interval可以选择1min,5min等,apikey就是我的api。
# 具体的参数内容,要去网站里面查看。

APIkey = 'UNI5VMZX74ZM8AQ8'
timeseries = 'TIME_SERIES_INTRADAY'
ticker = 'AAPL'
interval = '1min'
# 这几行就定义好我们在url中会选择的参数了

f = urllib.request.urlopen(url)
# 向url发送了请求,并将返回的信息储存在f中

dat = f.read()
# 将信息读取入dat中,但是这个时候信息还是以json的形式打包的所以需要用decode解码一下

js = dat.decode('utf8')
# .decode('utf8')以utf-8编译符把字符标准化,这个过程有点像解压缩包
f.close()

parse_data = json.loads(js)
# json.loads()指把json的数据读取之后,转化为一个字典的样子。

ps = parse_data['Time Series (1min)']
df = pd.DataFrame.from_dict(ps, orient = 'index') 
# orient = 是指在字典中,我们要把每一个键当成一个index还是columns,默认columns
df.columns = ['Open', 'High', 'Low', 'Close', 'Volume']
# 给列重新定名
# 这样这个数据就读取出来了。但是因为我们读出来的数据都是string的类型,所以需要用一个函数将其变成numeric类型以及datetime类型。
########################################################

cols = df.columns
df[cols] = df[cols].apply(pd.to_numeric, errors = 'coerce')
df.index = pd.to_datetime(df.index, format = '%Y-%m-%d')
# 这一步就叫数据的清洗,data clean.

这样一个完整的数据就出来了

补充:apply和lambda函数

df.apply(np.sqrt)
#.apply()会作用于数据的每一列
df.apply(np.sum)
pd.to_numeric(df[1])
# pd.to_numeric() 只能作用于list、tuple、1-2 array、Series,所以不能直接对dataframe使用要用.apply(pd.to_numeric)这样子来处理。

########################################################

​ 在一些小的、只用一次的函数中,我们就可以定义为lambda函数。

df.apply(lambda x: x+1)
# x代表的就是每一列数据
df[['A','B']] = df[['A','B']].apply(lambda x: x*2)
# 在这里要强调一下为什么是双括号,因为df[[]]代表的是一个数据框。

​ 然后,为了这个读取和清晰的流程,变成一个固定的,我们将其定义成一个函数。

import matplotlib.pyplot as plt
import seaborn as sns
import pandas as pd
import urllib.request
import json

def import_data(timeseries, ticker, interval, size, key_name, APIkey):
    if timeseries == 'TIME_SERIES_INTRADAY':
        url =  'https://www.alphavantage.co/query?function='+timeseries+'&symbol='+ticker+'&interval='+interval+'&apikey='+APIkey
    if timeseries == 'TIME_SERIES_DAILY':
        url = 'https://www.alphavantage.co/query?function='+timeseries+'&symbol='+ticker+'&outputsize='+size+'&apikey='+APIkey
# 这里的两个if判断,是因为Intraday和Daily两种数据调用的链接地址参数是不同的。
    f = urllib.request.urlopen(url)
    dat = f.read()
    js = dat.decode('utf8')
    f.close()
    parse_data = json.loads(js)
    ps = parse_data[key_name]
    df = pd.DataFrame.from_dict(ps, orient = 'index')
    df.columns = ['Open', 'High', 'Low', 'Close', 'Volume']
    return df

def data_clean(df):
    cols = df.columns
    df[cols] = df[cols].apply(pd.to_numeric, errors = 'coerce')
    df.index = pd.to_datetime(df.index, format = '%Y-%m-%d')
    return df

timeseries = 'TIME_SERIES_DAILY'
ticker_list = ['AAPL', 'MFST', 'GOOG', 'FB']
interval = ''
key_name = 'Time Series (Daily)'
APIkey = 'UNI5VMZX74ZM8AQ8'
size = 'compact'

stock_list = {}
for ticker in ticker_list:
    temp_dat = import_data(timeseries, ticker, interval, size, key_name, APIkey)
    stock_list[ticker] = data_clean(temp_dat)

Day 10 蜡烛图

蜡烛图的绘制

​ 蜡烛图,也叫K线图,股市及期货市场中的K线图的画法包含4个数据,开盘价、最高价、最低价、收盘价。

# 同样的,先用Day 9的代码,拿到我们从API调用的数据。
from matplotlib.dates import DateFormatter, WeekdayLocator, DayLocator, MONDAY, date2num
from mpl_finance import candlestick_ohlc
import numpy as np
# 这些调用的包就比较专业了,在这里不做细说。

quotes = list(zip(list(date2num(data.index.tolist())), data['Open'].tolist(), data['High'].tolist(), data['Low'].tolist(), data['Close'].tolist()))
quotes
# 我们要把数据变成一个quotes的格式,第一列到第五列分别是日期、开盘、最高、最低、收盘
# .tolist()可以把数据变成list,date2num是把时间变成数据的一种函数。

# 接下来要对X轴进行标注,反映数据的时间,这个操作算是比较高级的操作了,我并看不懂,以后再说
mondays = WeekdayLocator(MONDAY) 
# 定位到哪一天,这里选择了MONDAY
alldays = DayLocator()
# Daylocator()表示在横坐标轴上以一天为最小的单位
weekFormatter = DateFormatter('%b %d')
# DateFormatter('%b %d')把日期填成什么样的形式,%b - 用英文书写月份,%d - 用数字表示天。%Y - 表示年份。

fig = plt.figure(figsize = (15, 9))
ax = fig.add_subplot(1,1,1)

ax.xaxis.set_major_locator(mondays)
ax.xaxis.set_minor_locator(alldays)
ax.xaxis.set_major_formatter(weekFormatter)
# 把这些对x轴的设置给添加进去

candlestick_ohlc(ax, quotes, colorup = 'red', colordown = 'green', width = 1*.4)
plt.title('AAPL')
plt.show()
# 这样蜡烛图就OK了,接下来我们将这个流程定义成一个函数
def draw_candlestick(data, ticker, label_date = None, x1 = 0, x2 = 0):
    mondays = WeekdayLocator(MONDAY) 
    alldays = DayLocator()
    weekFormatter = DateFormatter('%b %d')
    
    fig = plt.figure(figsize = (15,9))
    ax = fig.add_subplot(1,1,1)

    ax.xaxis.set_major_locator(mondays)
    ax.xaxis.set_minor_locator(alldays)
    ax.xaxis.set_major_formatter(weekFormatter)
    
    quotes =list(zip(list(date2num(data.index.tolist())),
                     data['Open'].tolist(),
                     data['High'].tolist(), 
                     data['Low'].tolist(), 
                     data['Close'].tolist()))
    
    candlestick_ohlc(ax, quotes, colorup = 'red', 
                     colordown = 'green', width = 1*.4)
    
    if label_date != None:
        dt = date2num(pd.to_datetime(label_date, format
                                     = '%Y-%m-%d'))
        ax.annotate(str(data.loc[label_date, 'High']),
                    xy = (dt-2, x1))
        ax.annotate(str(data.loc[label_date, 'Low']),
                    xy = (dt-2, x2))
    plt.title(ticker)
    plt.show()

Datetime的用法

data['week'] = pd.to_datetime(data.index).map(lambda x:x.isocalendar()[1])
# .isocalendar()可以返回3个信息,年份,星期,天;提取星期的话,就是第2个数值

#如果涉及到提取月份的话,我们可以直接用.month函数(注意:这个month后面不需要接括号
data['month'] = pd.to_datetime(data.index).map(lambda x:x.month)
grouped = data.groupby(['month'])

groupby的用法

data['Week'] = pd.to_datetime(data.index).map(lambda x: x.isocalendar()[1])

grouped = data.groupby(['Week'])

for i,x in grouped:
    print(i)
    print(x)

绘制以月为单位的蜡烛图

data['month'] = pd.to_datetime(data.index).map(lambda x:x.month)
grouped = data.groupby(['month'])

# for i,x in grouped:
#    print(i)
#    print(x)
    
plotdata = pd.DataFrame({'Open':[],
                         'High':[],
                         'Low':[],
                         'Close':[]})
for i,x in grouped:
    plotdata = plotdata.append(pd.DataFrame(
        {'Open': x.iloc[0,0],
         'High':max(x.High),
         'Low':min(x.Low),
         'Close':x.iloc[-1,3]},
        index = [x.index[0]]))

draw_candlestick(plotdata, 'AAPL',label_date = None, x1=0,x2=0)

补充:移动平均数

data['7d'] = data['Close'].rolling(window = 7, center = False).mean()
data['15d'] = data['Close'].rolling(window = 15, center = False).mean()
# 股价价格信息变动分析中,移动平均数,指定时间段对时间序列数据进行移动计算平均值,是一个移动的过程。
# rolling()用于计算移动平均数,windows是指几天的移动平均数

# 可以把移动平均数也画到图中,使图更高大上。
months = WeekdayLocator(MONDAY) 
alldays = DayLocator()
monthFormatter = DateFormatter('%b %d')

fig = plt.figure(figsize = (15,9))
ax = fig.add_subplot(1,1,1)

ax.xaxis.set_major_locator(months)
ax.xaxis.set_minor_locator(alldays)
ax.xaxis.set_major_formatter(monthFormatter)

quotes =list(zip(list(date2num(data.index.tolist())),
                 data['Open'].tolist(),
                 data['High'].tolist(), 
                 data['Low'].tolist(), 
                 data['Close'].tolist()))

candlestick_ohlc(ax, quotes, colorup = 'red', 
                 colordown = 'green', width = 1*.4)
plt.plot(data.index, data['7d'])
plt.plot(data.index, data['15d'])

plt.title(ticker)
plt.show()

补充: zip函数

list1 = [1,2,3]
list2 = [4,5,6]
list3 = [7,8,9]
list(zip(list1,list2,list3))
# zip把多个列表或者多个数列里每个元素对应位置的数集合在一起

结束

​好了,棕榈的python培训就结束了,虽然看起来学到了很多东西,但其实在实际应用的时候还会遇到很多奇怪的问题。比如说,我想将pdf中的数据提取出来,还需要学习一些正则、或者是其他数据的读取、以及简易的网络爬虫。另外,在数据清洗时,也可能遇到很多奇怪的问题,需要用到strip、split等函数进行拆分、去空格等等,以及数据分析上,本次培训没有任何介绍。总而言之,还有很长的要走,慢慢来吧。

猜你喜欢

转载自blog.csdn.net/qq_42081859/article/details/83662381