楼主: tkfy920
3889 17

[原创博文] 【手把手教你】玩转Python金融量化利器之Pandas [推广有奖]

  • 8关注
  • 38粉丝

Python金融量化

讲师

49%

还不是VIP/贵宾

-

威望
0
论坛币
467 个
通用积分
22.2661
学术水平
27 点
热心指数
25 点
信用等级
19 点
经验
64993 点
帖子
473
精华
0
在线时间
513 小时
注册时间
2008-3-28
最后登录
2024-3-15

楼主
tkfy920 在职认证  学生认证  发表于 2018-10-22 12:57:24 |只看作者 |坛友微信交流群|倒序 |AI写论文
相似文件 换一批

+2 论坛币
k人 参与回答

经管之家送您一份

应届毕业生专属福利!

求职就业群
赵安豆老师微信:zhaoandou666

经管之家联合CDA

送您一个全额奖学金名额~ !

感谢您参与论坛问题回答

经管之家送您两个论坛币!

+2 论坛币

贵有恒,何必三更起五更眠。最无益,只怕一日曝十日寒。

                                                                  ——毛泽东

前言


“手把手教你”系列将为Python初学者一一介绍Python在量化金融中运用最广泛的几个库(Library): NumPy(数组、线性代数)、SciPy(统计)、pandas(时间序列、数据分析)、matplotlib(可视化分析)。建议安装Anaconda软件(自带上述常见库),并使用Jupyter Notebook交互学习。

对于Python零基础的请关注公众号CuteHand,并回复Python入门,奉上Python的程序安装和入门应用指南。对于Python的高阶学习,如数据分析挖掘、机器学习和量化投资,请继续关注公众号的动态。

Pandas的数据结构类型:


·      Series (序列:一维列表)

·      DataFrame (数据框:二维表)

1. Series


定义:数据表中的一列或一行,观测向量为一维数组,对于任意一组个体某一属性的观测可抽象为Series的概念。Series默认由index和values构成。

import pandas as pd
import 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)

可以在创建Series时添加index,并可使用Series.index查看具体的index。需要注意的一点是,当从数组创建Series时,若指定index,那么index长度要和data的长度一致

np.random.seed(2)
s=Series(np.random.randn(5),index=['a','b','c','d','e'])
print (s)
s.index

·      通过字典(dict)来创建Series。  

stocks={'中国平安':'601318','格力电器':'000651','招商银行':'600036',
        '中信证券':'600030','贵州茅台':'600519'}
Series_stocks = Series(stocks)
print (s)

·      使用字典创建Series时指定index的情形(index长度不必和字典相同)。

Series(stocks, index=['中国平安', '格力电器', '招商银行', '中信证券',
                      '工业富联'])
#注意,在原来的stocks(dict)里没有‘工业富联’,因此值为‘NaN’

·      给数据序列和index命名:

Series_stocks.name='股票代码'        #注意python是使用.号来连接和调用
Series_stocks.index.name='股票名称'
print(Series_stocks)

1.2 Series数据的访问

Series对象的下标运算同时支持位置和标签两种方式

np.random.seed(3)
data=np.random.randn(5)
s = Series(data,index=['a', 'b', 'c', 'd', 'e'])
s

s[:2]   #取出第0、1行数据

s[[2,0,4]]  #取出第2、0、4行数据

s[['e', 'a']] #取出‘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'])
s

#排序
s.sort_index(ascending=True) #按index从小到大,False从大到小

s.sort_values(ascending=True)

s.rank(method='average',ascending=True,axis=0) #每个数的平均排名

#返回含有最大值的索引位置:
print(s.idxmax())
#返回含有最小值的索引位置:
print(s.idxmin())

2 Pandas数据结构:DataFrame


DataFrame是一个二维的数据结构,通过数据组,index和columns构成

2.1 DataFrame数据表的创建

DataFrame是多个Series的集合体。  
先创建一个值是Series的字典,并转换为DataFrame。

#通过字典创建DataFrame
d={'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)

#可以使用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也可以从值是数组的字典创建,但是各个数组的长度需要相同:
d = {'one': [1., 2., 3., 4.], 'two': [4., 3., 2., 1.]}
df = DataFrame(d, index=['a', 'b', 'c', 'd'])
df

#值非数组时,没有这一限制,并且缺失值补成NaN
d= [{'a': 1.6, 'b': 2}, {'a': 3, 'b': 6, 'c': 9}]
df = DataFrame(d)
df

#另一种创建DataFrame的方法十分有用,那就是使用concat函数基于Series
#或者DataFrame创建一个DataFrame
a = 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)

其中的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])
    df = pd.concat([df, a], axis=0)
print (df)

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])
    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:\n",df['b'])
print ("df.b:\n",df.b)
print ("df[['a','b']]:\n",df[['a', 'd']])

#访问特定的元素可以如Series一样使用下标或者是索引:
print (df['b'][2])       #第b列,第3行(从0开始算)
print (df['b']['gamma']) #第b列,gamma对应行

##### df.loc['列或行名'],df.iloc[n]第n行,df.iloc[:,n]第n列

#若需要选取行,可以使用dataframe.iloc按下标选取,
#或者使用dataframe.loc按索引选取
print (df.iloc[1])    #选取第一行元素
print (df.loc['beta'])#选取beta对应行元素

#选取行还可以使用切片的方式或者是布尔类型的向量:
print ("切片取数:\n",df[1:3])
bool_vec = [True, False, True, True, False]
print ("根据布尔类型取值:\n",df[bool_vec]) #相当于选取第0、2、3行

#行列组合起来选取数据:
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']])

#如果不是需要访问特定行列,而只是某个特殊位置的元素的话,
#dataframe.at和dataframe.iat
#是最快的方式,它们分别用于使用索引和下标进行访问
print(df)
print (df.iat[2, 3])  #相当于第3行第4列
print (df.at['gamma', 'd'])

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=5
df.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)

#数据转置
# df.T

根据索引排序数据排序:(按行axis=0或列axis=1)

df.sort_index(axis=1,ascending=False)

#按某列的值排序
df.sort_values('A')  #按A列的值从小到大排序

#数据选取loc和iloc
df.loc[dates[0]]


Name: 2018-01-31 00:00:00, dtype: float64

df.loc['20180131':'20180430',['A','C']]  #根据标签取数

df.iloc[1:3,1:4]  #根据所在位置取数,注意从0开始数

df.iloc[[1,3,5],[0,3]]  #根据特定行和列取数

df[df.A>0] #相当于取出A列大于0时的数据列表

df[df>0]  #显示值大于0的数,其余使用NaN代替

数据筛选isin()

df2=df.copy() #复制df数据
df2['E']=np.arange(12)
df2

df2[df2['E'].isin([0,2,4])]

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

df3.iat[3,3]=np.NaN  #令第3行第3列的数为缺失值(0.129151)
df3.iat[1,2]=np.NaN  #令第1行第2列的数为缺失值(1.127064)
df3

#丢弃存在缺失值的行
#设定how=all只会删除那些全是NaN的行:
df3.dropna(how='any')

#删除列也一样,设置axis=1
df3.dropna(how='any',axis=1)

#thresh参数,如thresh=4,一行中至少有4个非NaN值,否则删除
df3.iloc[2,2]=np.NaN
df3.dropna(thresh=4)

填充缺失值  
fillna 还可以使用 method 参数   
method 可以使用下面的方法   
1 . pad/ffill:用前一个非缺失值去填充该缺失值  
2 . backfill/bfill:用下一个非缺失值填充该缺失值

df3.fillna(method='ffill')

df3.fillna(method='bfill')

df3

#使在改变DataFrame 和 Series 的操作时,会返回一个新的对象,
#原对象不变,如果要改变原对象,可以添加参数 inplace = True用列均值填充
#使用该列的均值填充
df3['C'].fillna(df3['C'].mean(),inplace=True)
df3

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

描述性统计 df.describe()

df4.describe()

df4.mean() #均值,默认按列axis=0

df4.mean(axis=1)  #按行

对数据使用函数df.apply()

df4.apply(np.cumsum) #np.cumsum()累加函数

df4.apply(lambda x:x.max()-x.min()) #lambda自定义函数
#相当于计算每列里最大值-最小值

df4['E']=['a','a','a','b','b']
df4

#计算某个值出现评率
df4['E'].value_counts()

a    3
b    2
Name: E, dtype: int64

5、数据合并


#Concat()
d1=pd.Series(range(5))
print(d1)
d2=pd.Series(range(5,10))
print(d2)

pd.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)

#增加1行数据:Append()
df = pd.DataFrame(np.random.randn(3, 3), columns=['A','B','C'])
df

s=pd.Series([1.,1,1],index=list('ABC'))
df.append(s,ignore_index=True)

聚类分析 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']).sum()  #以A列特征分类并加总

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 plt
from pylab import mpl  
mpl.rcParams['font.sans-serif'] = ['SimHei'] # 用来正常显示中文标签
mpl.rcParams['axes.unicode_minus']=False  # 用来正常显示负号
%matplotlib inline

ts = pd.Series(np.random.randn(1000), index=pd.date_range('1/1/2000',
               periods=1000))
ts = ts.cumsum()
ts.plot(figsize=(12,8))


1.png

import pandas as pd
df.index=pd.to_datetime(df['date'])
df['close'].plot(figsize=(12,8))
plt.title("上证指数走势")

2.png


详细内容可以阅读CuteHand: https://mp.weixin.qq.com/s/TOql9CQEXWrB-trpVt74_Q

二维码

扫码加我 拉你入群

请注明:姓名-公司-职位

以便审核进群资格,未注明则拒绝

关键词:金融量化 Python Pandas

回帖推荐

wdgwz 发表于9楼  查看完整内容

资料不错,pandas资料不错 vnpy是弱鸡架构,性能只有python合理架构1/20,不适合做实盘交易
已有 2 人评分经验 学术水平 热心指数 信用等级 收起 理由
娟儿1995 + 1 + 1 + 1 精彩帖子
cheetahfly + 100 观点有启发

总评分: 经验 + 100  学术水平 + 1  热心指数 + 1  信用等级 + 1   查看全部评分

当一个人把爱倾注于心灵的深处,有什么样的高度不能踩在脚下。
沙发
tkfy920 在职认证  学生认证  发表于 2018-10-22 14:59:14 |只看作者 |坛友微信交流群
【手把手】教你用Python获取财经数据和可视化分析
详细参考: https://bbs.pinggu.org/forum.php?mod=viewthread&tid=6682787&page=1&from^^uid=547554

使用道具

藤椅
申雪桐 发表于 2018-10-25 22:35:57 |只看作者 |坛友微信交流群
感谢楼主分享,好好学习资料

使用道具

板凳
baixiaofei5 发表于 2018-10-25 22:37:21 |只看作者 |坛友微信交流群
PANDA我的菜

使用道具

报纸
tkfy920 在职认证  学生认证  发表于 2018-10-28 10:36:32 |只看作者 |坛友微信交流群
【手把手教你】Python金融财务分析  https://mp.weixin.qq.com/s/EF3qrMCCUNjFTY-7MeTJgA

使用道具

地板
花茶物语 发表于 2018-10-29 09:18:58 |只看作者 |坛友微信交流群
谢谢分享

使用道具

7
tkfy920 在职认证  学生认证  发表于 2018-11-19 11:32:53 |只看作者 |坛友微信交流群
扫描下面二维码,关注Python金融量化,免费获取源代码和金融干货。

python金融量化.jpg (26.88 KB)

python金融量化.jpg

使用道具

8
wdgwz 在职认证  发表于 2018-11-19 12:01:34 |只看作者 |坛友微信交流群
资料不错,pandas资料不错



vnpy是弱鸡架构,性能只有python合理架构1/20,不适合做实盘交易

使用道具

9
tkfy920 在职认证  学生认证  发表于 2018-11-20 18:01:11 |只看作者 |坛友微信交流群
分享知识,点亮智慧

使用道具

10
tkfy920 在职认证  学生认证  发表于 2018-11-21 11:29:15 |只看作者 |坛友微信交流群
手把手教你使用python的金融量化利器pandas

使用道具

您需要登录后才可以回帖 登录 | 我要注册

本版微信群
加好友,备注cda
拉您进交流群

京ICP备16021002-2号 京B2-20170662号 京公网安备 11010802022788号 论坛法律顾问:王进律师 知识产权保护声明   免责及隐私声明

GMT+8, 2024-4-20 01:34