Pandas是一个python的开源库,它基于Numpy,提供了多种高性能且易于使用的数据结构。Pandas最初被用作金融数据分析工具而开发,由于它有着强大的功能,目前广泛应用于数据分析、机器学习以及量化投资等。下面来跟随作者一起认识下Pandas吧!

1 如何开始

Pandas安装方式十分简单,如果使用Anaconda,Anaconda默认就已经为我们安装好了Pandas,直接拿来用就可以了,推荐使用这种方式。

如果不用Anaconda,只需执行如下命令即可:

pipinstallpandas

像其他python库一样,使用之前需要导入,通常采用如下方式:

importpandasaspd

2 Pandas数据结构

Pandas的数据结构包括 SeriesDataFrame以及 Panel,这些数据结构基于 Numpy,因此效率很高。其中 DataFrame最为常用,是Pandas最主要的数据结构。所有Pandas数据结构都是值可变的,除 Series外都是大小(Size)可变的, Series大小不可变。

Series

Series是一维的类似的数组的对象,它包含一个数组的数据(任意NumPy的数据类型)和一个与数组关联的索引 。

>>>importpandasaspd>>>importnumpyasnp>>>s=pd.Series(np.random.randn(4))>>>s00.10278011.52300121.77006730.437553dtype:float64

可以看到Pandas默认为我们生成了索引,它的结构如下表所示:

01230.1027801.5230011.7700670.437553

我们也可以使用 index关键字为其指定索引:

>>>s=pd.Series(np.random.randn(4),index=['a','b','c','d'])>>>sa-0.316668b0.083363c-0.520227d-1.024034dtype:float64

DataFrame

DataFrame是二维的、类似表格的对象,是使用最为广泛的Pandas数据结构。DataFrame有行和列的索引,访问便捷。它可以被看作是Series的字典:

>>>data={'name':['张三','李四','王五'],...'gender':['M','F','M'],...'height':[174,160,185],...'weight':[80,48,70]}>>>frame=pd.DataFrame(data)>>>framenamegenderheightweight0张三M174801李四F160482王五M18570

结构如下表所示


namegenderheightweight0张三M174801李四F160482王五M18570

一方面,我们可以使用 columns关键字指定DataFrame列的顺序,DataFrame的列将会严格按照 columns所指定的顺序排列;另一方面,与Series相同,我们可以使用 index关键字为其指定索引:

>>>frame2=pd.DataFrame(data,columns=['name','gender','weight'],...index=['one','two','three'])>>>>>>frame2namegenderweightone张三M80two李四F48three王五M70

需要注意的是,DataFrame的同一列允许有不同类型的值(数字,字符串,布尔等),这便意味着:我们可以将 王五weight设置为 F

3 数据访问和遍历

DataFrame支持按下标访问:

>>> frame2.iloc[0]

name 张三

gender M

weight 80

Name: one, dtype: object


>>> frame2.iloc[0]['weight']

80

也支持按索引访问:

>>> frame2.loc['two']

name 李四

gender F

weight 48

Name: two, dtype: object


>>> frame2.loc['two']['name']

'李四'

因此,DataFrame也支持如下两种遍历方式:

>>>foriinrange(0,len(frame2)):...print(frame2.iloc[i])***输出结果略***

>>>forindex,rowinframe2.iterrows():...print(row)***输出结果略***

4 添加和删除列

如果我们想增加一列,也非常方便,如计算BMI指数:

>>>frame['BMI']=frame['weight']/(frame['height']*frame['height']/10000)>>>framenamegenderheightweightBMI0张三M1748026.4235701李四F1604818.7500002王五M1857020.452885

仅需一行代码而无需遍历。

删除列:

>>>delframe2['gender']>>>frame2nameweightone张三80two李四48three王五70

5 添加和删除行

添加行

>>>frame3=pd.DataFrame([['小红',46],['小明',68]],columns=['name','weight'],index=['four','five'])>>>frame4=frame2.append(frame3)>>>frame4nameweightone张三80two李四48three王五70four小红46five小明68

删除行

>>>frame4.drop('four')nameweightone张三80two李四48three王五70five小明68

6 数据筛选

按下标取出前两条记录

>>>frame[:2]namegenderheightweightBMI0张三M1748026.423571李四F1604818.75000

按其他条件筛选

如找到BMI>20的记录:

>>>mask=(frame['BMI']>20)>>>frame.loc[mask]namegenderheightweightBMI0张三M1748026.4235702王五M1857020.452885

DataFrame还支持许多其他的操作,篇幅有限,在此不一一展开。

7 Panel

Panel是三维的数据结构,可以看作是DataFrame的字典,这种数据结构使用很少,此处略过不提。

Pandas实战

学习技术是为了更好的工作和生活,抛开应用,技术也就失去了存在的意义。本文开篇中提到,Pandas作为数据分析工具的一个重要应用场景是量化投资,在此我想分享一下使用pandas的一个场景:

我想筛选出A股市场中过去60个交易日表现好的那些股票。关于表现好,也许每个人都有自己的看法,我的标准如下

涨幅够大,区间累计涨幅达60%以上

回撤小,区间内任意单个交易日跌幅不超过7%,包括高开低走7%(套人的不算好股票);区间内任意连续两个交易日累计跌幅不超过10%,包括连续两个交易日高开低走10%

我使用的数据源是TuShare,它提供了A股复权日线图,不过它没有提供复权数据的每日涨跌幅,所以我们需要对他进行处理:

>>>importtushareasts>>>importtalibastl>>>data=ts.get_k_data('300573',autype='qfq')>>>data['p_change']=tl.ROC(data['close'],1)

此处使用了TALib,一个开源的金融数据分析工具。

完成初步的数据处理之后,我们就可以运行筛选条件了,截取代码片段如下:

threshold = 60

if len(data) < threshold:

return False

data = data.tail(n=threshold)


ratio_increase = (data.iloc[-1]['close'] - data.iloc[0]['close']) / data.iloc[0]['close']

if ratio_increase < 0.6:

return False


for i in range(1, len(data)):

if data.iloc[i - 1]['p_change'] < -7 \

or (data.iloc[i]['close'] - data.iloc[i]['open'])/data.iloc[i]['open'] * 100 < -7 \

or data.iloc[i - 1]['p_change'] + data.iloc[i]['p_change'] < -10 \

or (data.iloc[i]['close'] - data.iloc[i - 1]['open']) / data.iloc[i - 1]['open'] * 100 < -10:

return False


return True

最后的结果如下:

[('603986','兆易创新'),('603882','金域医学'),('603501','韦尔股份'),('300782','卓胜微'),('300622','博士眼镜'),('300502','新易盛'),('300492','山鼎设计'),('300433','蓝思科技'),('300223','北京君正'),('002917','金奥博'),('002892','科力尔'),('002876','三利谱'),('002850','科达利'),('002819','东方中科'),('002600','领益智造'),('002241','歌尔股份'),('000049','德赛电池')]

可以看到其中科技股独领风骚,谁让我们大A是科技牛呢?