前言:
如今小伙伴们对“python 金融编程”大约比较着重,各位老铁们都想要分析一些“python 金融编程”的相关内容。那么小编同时在网摘上收集了一些对于“python 金融编程””的相关资讯,希望你们能喜欢,你们快快来了解一下吧!前言
“手把手教你”系列将为Python初学者一一介绍Python在量化金融中运用最广泛的几个库(Library): NumPy(数组、线性代数)、SciPy(统计)、pandas(时间序列、数据分析)、matplotlib(可视化分析)。建议安装Anaconda软件(自带上述常见库),并使用Jupyter Notebook交互学习。
Pandas的数据结构类型:
Series (序列:一维列表)DataFrame (数据框:二维表)
1. Series
定义:数据表中的一列或一行,观测向量为一维数组,对于任意一组个体某一属性的观测可抽象为Series的概念。Series默认由index和values构成。
import pandas as pdimport numpy as np
1.1 Series的创建
创建Series 创建一个Series的基本格式是s = Series(data, index=index, name=name)
np.random.seed(1) #使用随机种子,这样每次运行random结果一致,A=np.random.randn(5) print("A is an array:\n",A)S = pd.Series(A)print("S is a Series:\n",S)print("index: ", S.index) #默认创建索引,注意是从0开始print("values: ", S.values)A is an array: [ 1.62434536 -0.61175641 -0.52817175 -1.07296862 0.86540763]S is a Series: 0 1.6243451 -0.6117562 -0.5281723 -1.0729694 0.865408dtype: float64index: RangeIndex(start=0, stop=5, step=1)values: [ 1.62434536 -0.61175641 -0.52817175 -1.07296862 0.86540763]
可以在创建Series时添加index,并可使用Series.index查看具体的index。需要注意的一点是,
当从数组创建Series时,若指定index,那么index长度要和data的
长度一致
加入千人交流基地:864573496 一起讨论问题,一起分享资源,还是一个挺不错的学习基地的!欢迎大家加入!
1.2 Series数据的访问
Series对象的下标运算同时支持位置和标签两种方式
np.random.seed(3)data=np.random.randn(5)s = Series(data,index=['a', 'b', 'c', 'd', 'e'])sa 1.624345b -0.611756c -0.528172d -1.072969e 0.865408dtype: float64s[:2] #取出第0、1行数据a -0.670228b 0.488043dtype: float64s[[2,0,4]] #取出第2、0、4行数据c -0.528172a 1.624345e 0.865408dtype: float64s[['e', 'a']] #取出‘e’、‘a’对应数据e 0.865408a 1.624345dtype: float64
1.3 Series排序函数
np.random.seed(3)data=np.random.randn(10)s = Series(data,index=['j','a', 'c','b', 'd', 'e','h','f','g','i'])sj 1.788628a 0.436510c 0.096497b -1.863493d -0.277388e -0.354759h -0.082741f -0.627001g -0.043818i -0.477218dtype: float64#排序s.sort_index(ascending=True) #按index从小到大,False从大到小a 0.436510b -1.863493c 0.096497d -0.277388e -0.354759f -0.627001g -0.043818h -0.082741i -0.477218j 1.788628dtype: float64s.sort_values(ascending=True)b -1.863493f -0.627001i -0.477218e -0.354759d -0.277388h -0.082741g -0.043818c 0.096497a 0.436510j 1.788628dtype: float64s.rank(method='average',ascending=True,axis=0) #每个数的平均排名j 10.0a 9.0c 8.0b 1.0d 5.0e 4.0h 6.0f 2.0g 7.0i 3.0dtype: float64#返回含有最大值的索引位置: print(s.idxmax())#返回含有最小值的索引位置: print(s.idxmin())jb根据索引返回已排序的新对象:Series.sort_index(ascending=True)根据值返回已排序的对象,NaN值在末尾:Series.sort_values(ascending=True)为各组分配一个平均排名:Series.rank(method='average',ascending=True,axis=0) rank的method选项: 'average':在相等分组中,为各个值分配平均排名 'max','min':使用整个分组中的最小排名'first':按值在原始数据中出现的顺序排名返回含有最大值的索引位置:Series.idxmax()返回含有最小值的索引位置:Series.idxmin()
2 Pandas数据结构:DataFrame
DataFrame是一个二维的数据结构,通过数据组,index和columns构成
2.1 DataFrame数据表的创建
DataFrame是多个Series的集合体。
先创建一个值是Series的字典,并转换为DataFrame。
#通过字典创建DataFramed={'one':pd.Series([1.,2.,3.],index=['a','b','c']), 'two':pd.Series([1.,2.,3.,4.,],index=['a','b','c','d']), 'three':range(4), 'four':1., 'five':'f'}df=pd.DataFrame(d)print (df) one two three four fivea 1.0 1.0 0 1.0 fb 2.0 2.0 1 1.0 fc 3.0 3.0 2 1.0 fd NaN 4.0 3 1.0 f#可以使用dataframe.index和dataframe.columns来查看DataFrame的行和列,#dataframe.values则以数组的形式返回DataFrame的元素print ("DataFrame index:\n",df.index)print ("DataFrame columns:\n",df.columns)print ("DataFrame values:\n",df.values)DataFrame index: Index(['a', 'b', 'c', 'd'], dtype='object')DataFrame columns: Index(['one', 'two', 'three', 'four', 'five'], dtype='object')DataFrame values: [[1.0 1.0 0 1.0 'f'] [2.0 2.0 1 1.0 'f'] [3.0 3.0 2 1.0 'f'] [nan 4.0 3 1.0 'f']]#DataFrame也可以从值是数组的字典创建,但是各个数组的长度需要相同:d = {'one': [1., 2., 3., 4.], 'two': [4., 3., 2., 1.]}df = DataFrame(d, index=['a', 'b', 'c', 'd'])print df one twoa 1.0 4.0b 2.0 3.0c 3.0 2.0d 4.0 1.0#值非数组时,没有这一限制,并且缺失值补成NaNd= [{'a': 1.6, 'b': 2}, {'a': 3, 'b': 6, 'c': 9}]df = DataFrame(d)print df a b c0 1.6 2 NaN1 3.0 6 9.0#在实际处理数据时,有时需要创建一个空的DataFrame,可以这么做df = DataFrame()print (df)Empty DataFrameColumns: []Index: []#另一种创建DataFrame的方法十分有用,那就是使用concat函数基于Series#或者DataFrame创建一个DataFramea = Series(range(5)) #range(5)产生0到4 b = Series(np.linspace(4, 20, 5)) #linspace(a,b,c)df = pd.concat([a, b], axis=1)print (df) 0 10 0 4.01 1 8.02 2 12.03 3 16.04 4 20.0
其中的axis=1表示按列进行合并,axis=0表示按行合并,
并且,Series都处理成一列,所以这里如果选axis=0的话,
将得到一个10×1的DataFrame。下面这个例子展示了如何按行合并
DataFrame成一个大的DataFrame:
df = DataFrame()index = ['alpha', 'beta', 'gamma', 'delta', 'eta']for i in range(5): a = DataFrame([np.linspace(i, 5*i, 5)], index=[index[i]]) df = pd.concat([df, a], axis=0)print (df) 0 1 2 3 4alpha 0.0 0.0 0.0 0.0 0.0beta 1.0 2.0 3.0 4.0 5.0gamma 2.0 4.0 6.0 8.0 10.0delta 3.0 6.0 9.0 12.0 15.0eta 4.0 8.0 12.0 16.0 20.0
2.2 DataFrame数据的访问
#DataFrame是以列作为操作的基础的,全部操作都想象成先从DataFrame里取一列,#再从这个Series取元素即可。#可以用datafrae.column_name选取列,也可以使用dataframe[]操作选取列df = DataFrame()index = ['alpha', 'beta', 'gamma', 'delta', 'eta']for i in range(5): a = DataFrame([np.linspace(i, 5*i, 5)], index=[index[i]]) df = pd.concat([df, a], axis=0)print('df: \n',df)print ("df[1]:\n",df[1])df.columns = ['a', 'b', 'c', 'd', 'e']print('df: \n',df)print ("df[b]:\n",df['b'])print ("df.b:\n",df.b)print ("df[['a','b']]:\n",df[['a', 'd']])df: 0 1 2 3 4alpha 0.0 0.0 0.0 0.0 0.0beta 1.0 2.0 3.0 4.0 5.0gamma 2.0 4.0 6.0 8.0 10.0delta 3.0 6.0 9.0 12.0 15.0eta 4.0 8.0 12.0 16.0 20.0df[1]: alpha 0.0beta 2.0gamma 4.0delta 6.0eta 8.0Name: 1, dtype: float64df: a b c d ealpha 0.0 0.0 0.0 0.0 0.0beta 1.0 2.0 3.0 4.0 5.0gamma 2.0 4.0 6.0 8.0 10.0delta 3.0 6.0 9.0 12.0 15.0eta 4.0 8.0 12.0 16.0 20.0df[b]: alpha 0.0beta 2.0gamma 4.0delta 6.0eta 8.0Name: b, dtype: float64df.b: alpha 0.0beta 2.0gamma 4.0delta 6.0eta 8.0Name: b, dtype: float64df[['a','b']]: a dalpha 0.0 0.0beta 1.0 4.0gamma 2.0 8.0delta 3.0 12.0eta 4.0 16.0#访问特定的元素可以如Series一样使用下标或者是索引:print (df['b'][2]) #第b列,第3行(从0开始算)print (df['b']['gamma']) #第b列,gamma对应行4.04.0##### df.loc['列或行名'],df.iloc[n]第n行,df.iloc[:,n]第n列#若需要选取行,可以使用dataframe.iloc按下标选取,#或者使用dataframe.loc按索引选取print (df.iloc[1]) #选取第一行元素print (df.loc['beta'])#选取beta对应行元素a 1.0b 2.0c 3.0d 4.0e 5.0Name: beta, dtype: float64a 1.0b 2.0c 3.0d 4.0e 5.0Name: beta, dtype: float64#选取行还可以使用切片的方式或者是布尔类型的向量:print ("切片取数:\n",df[1:3])bool_vec = [True, False, True, True, False]print ("根据布尔类型取值:\n",df[bool_vec]) #相当于选取第0、2、3行切片取数: a b c d ebeta 1.0 2.0 3.0 4.0 5.0gamma 2.0 4.0 6.0 8.0 10.0根据布尔类型取值: a b c d ealpha 0.0 0.0 0.0 0.0 0.0gamma 2.0 4.0 6.0 8.0 10.0delta 3.0 6.0 9.0 12.0 15.0#行列组合起来选取数据:print (df[['b', 'd']].iloc[[1, 3]])print (df.iloc[[1, 3]][['b', 'd']])print (df[['b', 'd']].loc[['beta', 'delta']])print (df.loc[['beta', 'delta']][['b', 'd']]) b dbeta 2.0 4.0delta 6.0 12.0 b dbeta 2.0 4.0delta 6.0 12.0 b dbeta 2.0 4.0delta 6.0 12.0 b dbeta 2.0 4.0delta 6.0 12.0#如果不是需要访问特定行列,而只是某个特殊位置的元素的话,#dataframe.at和dataframe.iat#是最快的方式,它们分别用于使用索引和下标进行访问print(df)print (df.iat[2, 3]) #相当于第3行第4列print (df.at['gamma', 'd']) a b c d ealpha 0.0 0.0 0.0 0.0 0.0beta 1.0 2.0 3.0 4.0 5.0gamma 2.0 4.0 6.0 8.0 10.0delta 3.0 6.0 9.0 12.0 15.0eta 4.0 8.0 12.0 16.0 20.08.08.0
2.3创建时间序列
pandas.date_range(start=None, end=None, periods=None, freq='D',
tz=None, normalize=False, name=None, closed=None, **kwargs)
dates=pd.date_range('20180101',periods=12,freq='m')print (dates)DatetimeIndex(['2018-01-31', '2018-02-28', '2018-03-31', '2018-04-30', '2018-05-31', '2018-06-30', '2018-07-31', '2018-08-31', '2018-09-30', '2018-10-31', '2018-11-30', '2018-12-31'], dtype='datetime64[ns]', freq='M')np.random.seed(5)df=pd.DataFrame(np.random.randn(12,4),index=dates, columns=list('ABCD'))df
#查看数据头n行 ,默认n=5df.head()
#查看数据最后3行df.tail(3)
#查看数据的index(索引),columns (列名)和数据print(df.index)DatetimeIndex(['2018-01-31', '2018-02-28', '2018-03-31', '2018-04-30', '2018-05-31', '2018-06-30', '2018-07-31', '2018-08-31', '2018-09-30', '2018-10-31', '2018-11-30', '2018-12-31'], dtype='datetime64[ns]', freq='M')print(df.columns)Index(['A', 'B', 'C', 'D'], dtype='object')print(df.values)[[ 0.44122749 -0.33087015 2.43077119 -0.25209213] [ 0.10960984 1.58248112 -0.9092324 -0.59163666] [ 0.18760323 -0.32986996 -1.19276461 -0.20487651] [-0.35882895 0.6034716 -1.66478853 -0.70017904] [ 1.15139101 1.85733101 -1.51117956 0.64484751] [-0.98060789 -0.85685315 -0.87187918 -0.42250793] [ 0.99643983 0.71242127 0.05914424 -0.36331088] [ 0.00328884 -0.10593044 0.79305332 -0.63157163] [-0.00619491 -0.10106761 -0.05230815 0.24921766] [ 0.19766009 1.33484857 -0.08687561 1.56153229] [-0.30585302 -0.47773142 0.10073819 0.35543847] [ 0.26961241 1.29196338 1.13934298 0.4944404 ]]#数据转置# df.T
根据索引排序数据排序:(按行axis=0或列axis=1)
df.sort_index(axis=1,ascending=False)
#按某列的值排序df.sort_values('A') #按A列的值从小到大排序
df.iloc[1:3,1:4] #根据所在位置取数,注意从0开始数
df[df>0] #显示值大于0的数,其余使用NaN代替
3. 缺失值处理
缺失值用NaN显示
date3=pd.date_range('20181001',periods=5)np.random.seed(6)data=np.random.randn(5,4)df3=pd.DataFrame(data,index=date3,columns=list('ABCD'))df3
#丢弃存在缺失值的行#设定how=all只会删除那些全是NaN的行:df3.dropna(how='any')
填充缺失值
fillna 还可以使用 method 参数
method 可以使用下面的方法
1 . pad/ffill:用前一个非缺失值去填充该缺失值
2 . backfill/bfill:用下一个非缺失值填充该缺失值
4、统计
date4=pd.date_range('20181001',periods=5)np.random.seed(7)data4=np.random.randn(5,4)df4=pd.DataFrame(data4,index=date3,columns=list('ABCD'))df4
df4.mean() #均值,默认按列axis=0A 0.595828B -0.000170C -0.112358D -0.899704dtype: float64df4.mean(axis=1) #按行2018-10-01 0.4162312018-10-02 -0.6356182018-10-03 0.2052952018-10-04 -0.3630122018-10-05 -0.143401Freq: D, dtype: float64
对数据使用函数df.apply()
df4.apply(np.cumsum) #np.cumsum()累加函数
df4.apply(lambda x:x.max()-x.min()) #lambda自定义函数#相当于计算每列里最大值-最小值A 2.479449B 1.066436C 0.899889D 2.162241dtype: float64df4['E']=['a','a','a','b','b']df4
5、数据合并
#Concat()d1=pd.Series(range(5))print(d1)d2=pd.Series(range(5,10))print(d2)0 01 12 23 34 4dtype: int640 51 62 73 84 9dtype: int64pd.concat([d1,d2],axis=1) #默认是纵向合并即axis=0
#pd.merge(left_on=None, right_on=None, left_index=False, #right_index=False)d1=pd.DataFrame(np.random.randn(3,3),columns=list('ABC'))print(d1)d2=pd.DataFrame(np.random.randn(3,3),columns=list('DEF'))print(d2)pd.merge(d1,d2,left_index=True, right_index=True) A B C0 1.766161 -0.329414 0.8407331 -0.179986 0.568062 -0.7528372 -1.708339 -1.803099 0.383122 D E F0 2.247595 0.269412 -0.5246051 1.912019 0.237302 0.1014342 0.252578 -0.132377 -0.309476
聚类分析 groupby
df = pd.DataFrame({'A' : ['true', 'false', 'true', 'false', 'true', 'false', 'true', 'false'], 'B' : ['one', 'one', 'two', 'three', 'two', 'two', 'one', 'three'], 'C' : np.random.randn(8), 'D' : np.random.randn(8)})df
df.groupby(['A','B']).sum()
数据透视表
df = pd.DataFrame({'A' : ['one', 'one', 'two', 'three'] * 3, 'B' : ['A', 'B', 'C'] * 4, 'C' : ['foo', 'foo', 'foo', 'bar', 'bar', 'bar'] * 2, 'D' : np.random.randn(12), 'E' : np.random.randn(12)})df
pd.pivot_table(df, values='D', index=['A', 'B'], columns=['C'])
6、数据可视化(画图)
import matplotlib.pyplot as pltfrom pylab import mpl mpl.rcParams['font.sans-serif'] = ['SimHei'] # 用来正常显示中文标签 mpl.rcParams['axes.unicode_minus']=False # 用来正常显示负号%matplotlib inlinets = pd.Series(np.random.randn(1000), index=pd.date_range('1/1/2000', periods=1000))ts = ts.cumsum()ts.plot(figsize=(12,8))#利用tushare包抓取股票数据并画图#得到的是DataFrame的数据结构import tushare as tsdf=ts.get_k_data('sh',start='1990-01-01')import pandas as pddf.index=pd.to_datetime(df['date'])df['close'].plot(figsize=(12,8))plt.title("上证指数走势")
标签: #python 金融编程