前言
“手把手教你”系列将向Python初学者介绍数量金融学中应用最广泛的几个库(Library): NumPy(数组、线性代数)、SciPy(统计)、pandas(时间序列、数据分析)、matplotlib(可视化分析)。建议安装Anaconda软件(带以上常用库),使用Jupyter Notebook进行互动学习。
Pandas的数据结构类型:
系列(系列:一维列表)数据框架(数据框架:二维表格)1. Series
定义:数据表中的一列或一行,观测向量是一维数组,任意一组个体的一个属性的观测都可以抽象为级数的概念。默认情况下,序列由索引和值组成。
进口熊猫作为PD进口熊猫作为NP1.1 Series的创建
创建序列创建序列的基本格式是S=Series (data,index=index,name=name)
Np.random.seed(1) #使用随机种子,这样每次运行random时结果都是一致的,a=np.random.randn (5) print ('a是数组3360 \ n ',a) s=pd.series (a) print ('s是系列3360 \ n ',S) print ('index3360,s. index) #索引是默认创建的。注意,打印从0开始(' values: '),S.values) A是一个数组: 1.62434536-0.61175641-0.52817175-1.0729686540763s是一个系列360 0 0 1.624451-0.61111552-0.52525 23-1.重要的是要注意到,
从数组创建序列时,如果指定了index,则index的长度应该与数据的长度相同。
一致长度
加入千人交流基地: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.624345 b-0.611756 c-0.528172d-1.072969 E 0.865408 dtype 3360 float 64s 33602 #取出第0行和第1行的数据,a-0.670228 b 0.488884 #取出数据C-0.528172 a 1.624345 e 0.865408d type : float 64S ' e ',' a' #取出对应数据e 0.865408 a 1.624345d type 3360 float 64 ' e '和' a '的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.788628 a 0.436510 c 0.096497 b-1.863493d-0.277388 e-0.354759h-0.082741 f-0.627001g-0.001g
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数据结构:DataFrameDataFrame是一个二维的数据结构,通过数据组,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'>
并且,Series都处理成一列,所以这里如果选axis=0的话,
将得到一个10×1的DataFrame。下面这个例子展示了如何按行合并
DataFrame成一个大的DataFrame:
df = DataFrame()index = <'alpha', 'beta', 'gamma', 'delta', 'eta'>for i in range(5): a = DataFrame(
#DataFrame是以列作为操作的基础的,全部操作都想象成先从DataFrame里取一列,#再从这个Series取元素即可。#可以用datafrae.column_name选取列,也可以使用dataframe<>操作选取列df = DataFrame()index = <'alpha', 'beta', 'gamma', 'delta', 'eta'>for i in range(5): a = DataFrame(
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
#查看数据头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
df.sort_index(axis=1,ascending=False)
#按某列的值排序df.sort_values('A') #按A列的值从小到大排序
df.iloc<1:3,1:4> #根据所在位置取数,注意从0开始数
df
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(
#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("上证指数走势")