请 [注册] 或 [登录]  | 返回主站

量化交易吧 /  数理科学 帖子:3364693 新帖:14

Python科学计算(2)- pandas库之数据查看、选择

英雄就是我发表于:5 月 10 日 00:22回复(1)

这是面向新用户的 Python 教程,并结合了 JoinQuant 获取到的数据进行了讲解。

如果你之前没有学过 Python, 或者对 Python 不熟,那不要再犹豫了,这个教程就是为你准备的!

更多内容请查看量化课堂 - Python编程板块。

本节概要: 主要介绍了 pandas库之数据查看、选择。平台获取的数据主要是 DataFrame 的形式,它便是 pandas 中的。

此节可是重中之重哦!

【Pyhton科学计算(2)】 - pandas库之数据查看、选择¶

pandas 是基于 Numpy 构建的,让以 Numpy 为中心的应用变得更加简单。

平台获取的数据主要是 DataFrame 的形式,它便是 pandas 中的。

除此之外,pandas 还包括 一位数组series 以及三维的Panel。

下面将进行详细介绍:

  • Series:一维数组,与Numpy中的一维array类似。二者与Python基本的数据结构List也很相近,其区别是:List中的元素可以是不同的数据类型,而Array和Series中则只允许存储相同的数据类型,这样可以更有效的使用内存,提高运算效率。

  • DataFrame:二维的表格型数据结构。很多功能与R中的data.frame类似。可以将DataFrame理解为Series的容器。以下的内容主要以DataFrame为主。

  • Panel :三维的数组,可以理解为DataFrame的容器。

Pandas官网,更多功能请参考http://pandas-docs.github.io/pandas-docs-travis/index.html

本节主要讲解 DataFrame 的数据查看与选择

# 首先导入库
import pandas as pd

1. Series¶

由一组数据(各种Numpy数据类型),以及一组与之相关的标签数据(即索引)组成。仅由一组数据即可产生最简单的Series,可以通过传递一个list对象来创建一个Series,pandas会默认创建整型索引,更多series内容请参考官网 http://pandas.pydata.org/pandas-docs/stable/generated/pandas.Series.html

创建一个Series:

s = pd.Series([1,3,5,np.nan,6,8])
s
0     1
1     3
2     5
3   NaN
4     6
5     8
dtype: float64

获取 Series 的索引:

s.index
Int64Index([0, 1, 2, 3, 4, 5], dtype='int64')

由于 Series 的用法在后续的 DataFrame 讲解及涉及,所以这了不做过多介绍,精彩内容请往下看。

2. DataFrame¶

DataFrame是一个表格型的数据结构,它含有一组有序的列,每一列的数据结构都是相同的,而不同的列之间则可以是不同的数据结构(数值、字符、布尔值等)。或者以数据库进行类比,DataFrame中的每一行是一个记录,名称为Index的一个元素,而每一列则为一个字段,是这个记录的一个属性。DataFrame既有行索引也有列索引,可以被看做由Series组成的字典(共用同一个索引)。

更多内容请参考:http://pandas.pydata.org/pandas-docs/stable/generated/pandas.DataFrame.html

2.1 创建一个DataFrame,包括一个numpy array, 时间索引和列名字:

dates = pd.date_range('20130101',periods=6)
dates
DatetimeIndex(['2013-01-01', '2013-01-02', '2013-01-03', '2013-01-04',
               '2013-01-05', '2013-01-06'],
              dtype='datetime64[ns]', freq='D', tz=None)
df = pd.DataFrame(np.random.randn(6,4),index=dates,columns=list('ABCD'))
df
A B C D
2013-01-01 -0.157119 -0.291521 -0.298163 0.259281
2013-01-02 -1.923994 0.179367 1.659175 0.643148
2013-01-03 -0.190008 -0.391425 0.875567 0.958852
2013-01-04 -0.919644 1.258374 -0.434826 0.164459
2013-01-05 -0.429443 1.075524 0.348728 1.077090
2013-01-06 -0.395215 0.527121 -2.103605 1.167503
df.<TAB>
  File "<ipython-input-6-e47a8920668a>", line 1
    df.<TAB>
       ^
SyntaxError: invalid syntax

2.2 查看数据

我们以平台获取的数据为例进行讲解:

# 获取平安银行近几个工作日的开盘价、最高价、最低价、收盘价。
df = get_price('000001.XSHE',start_date='2016-07-01', end_date='2016-07-20', frequency='daily', fields=['open','high','low','close'])
df
open high low close
2016-07-01 8.44 8.48 8.43 8.46
2016-07-04 8.44 8.60 8.42 8.55
2016-07-05 8.54 8.57 8.51 8.55
2016-07-06 8.54 8.56 8.50 8.53
2016-07-07 8.53 8.54 8.49 8.52
2016-07-08 8.53 8.53 8.48 8.49
2016-07-11 8.49 8.53 8.49 8.49
2016-07-12 8.49 8.63 8.49 8.62
2016-07-13 8.62 8.79 8.60 8.73
2016-07-14 8.71 8.74 8.65 8.68
2016-07-15 8.69 8.74 8.65 8.73
2016-07-18 8.73 8.82 8.71 8.78
2016-07-19 8.78 8.79 8.69 8.71
2016-07-20 8.70 8.73 8.69 8.70

查看前几条数据:

df.head()
open high low close
2016-07-01 8.44 8.48 8.43 8.46
2016-07-04 8.44 8.60 8.42 8.55
2016-07-05 8.54 8.57 8.51 8.55
2016-07-06 8.54 8.56 8.50 8.53
2016-07-07 8.53 8.54 8.49 8.52

查看后几条数据:

df.tail()
open high low close
2016-07-14 8.71 8.74 8.65 8.68
2016-07-15 8.69 8.74 8.65 8.73
2016-07-18 8.73 8.82 8.71 8.78
2016-07-19 8.78 8.79 8.69 8.71
2016-07-20 8.70 8.73 8.69 8.70

查看 DataFrame 的索引

df.index
DatetimeIndex(['2016-07-01', '2016-07-04', '2016-07-05', '2016-07-06',
               '2016-07-07', '2016-07-08', '2016-07-11', '2016-07-12',
               '2016-07-13', '2016-07-14', '2016-07-15', '2016-07-18',
               '2016-07-19', '2016-07-20'],
              dtype='datetime64[ns]', freq=None, tz=None)

查看 DataFrame 的列名

df.columns
Index([u'open', u'high', u'low', u'close'], dtype='object')

查看 DataFrame 的值

df.values
array([[ 8.44,  8.48,  8.43,  8.46],
       [ 8.44,  8.6 ,  8.42,  8.55],
       [ 8.54,  8.57,  8.51,  8.55],
       [ 8.54,  8.56,  8.5 ,  8.53],
       [ 8.53,  8.54,  8.49,  8.52],
       [ 8.53,  8.53,  8.48,  8.49],
       [ 8.49,  8.53,  8.49,  8.49],
       [ 8.49,  8.63,  8.49,  8.62],
       [ 8.62,  8.79,  8.6 ,  8.73],
       [ 8.71,  8.74,  8.65,  8.68],
       [ 8.69,  8.74,  8.65,  8.73],
       [ 8.73,  8.82,  8.71,  8.78],
       [ 8.78,  8.79,  8.69,  8.71],
       [ 8.7 ,  8.73,  8.69,  8.7 ]])

使用 describe() 函数对于数据的快速统计汇总:

df.describe()
open high low close
count 14.000000 14.000000 14.000000 14.000000
mean 8.587857 8.646429 8.557143 8.610000
std 0.114434 0.116923 0.102914 0.108769
min 8.440000 8.480000 8.420000 8.460000
25% 8.500000 8.545000 8.490000 8.522500
50% 8.540000 8.615000 8.505000 8.585000
75% 8.697500 8.740000 8.650000 8.707500
max 8.780000 8.820000 8.710000 8.780000

对数据的转置:

df.T
2016-07-01 00:00:00 2016-07-04 00:00:00 2016-07-05 00:00:00 2016-07-06 00:00:00 2016-07-07 00:00:00 2016-07-08 00:00:00 2016-07-11 00:00:00 2016-07-12 00:00:00 2016-07-13 00:00:00 2016-07-14 00:00:00 2016-07-15 00:00:00 2016-07-18 00:00:00 2016-07-19 00:00:00 2016-07-20 00:00:00
open 8.44 8.44 8.54 8.54 8.53 8.53 8.49 8.49 8.62 8.71 8.69 8.73 8.78 8.70
high 8.48 8.60 8.57 8.56 8.54 8.53 8.53 8.63 8.79 8.74 8.74 8.82 8.79 8.73
low 8.43 8.42 8.51 8.50 8.49 8.48 8.49 8.49 8.60 8.65 8.65 8.71 8.69 8.69
close 8.46 8.55 8.55 8.53 8.52 8.49 8.49 8.62 8.73 8.68 8.73 8.78 8.71 8.70

按列对 DataFrame 进行排序

df.sort(columns='open')
open high low close
2016-07-01 8.44 8.48 8.43 8.46
2016-07-04 8.44 8.60 8.42 8.55
2016-07-11 8.49 8.53 8.49 8.49
2016-07-12 8.49 8.63 8.49 8.62
2016-07-07 8.53 8.54 8.49 8.52
2016-07-08 8.53 8.53 8.48 8.49
2016-07-05 8.54 8.57 8.51 8.55
2016-07-06 8.54 8.56 8.50 8.53
2016-07-13 8.62 8.79 8.60 8.73
2016-07-15 8.69 8.74 8.65 8.73
2016-07-20 8.70 8.73 8.69 8.70
2016-07-14 8.71 8.74 8.65 8.68
2016-07-18 8.73 8.82 8.71 8.78
2016-07-19 8.78 8.79 8.69 8.71

2.3 选择数据¶

2.3.1 通过下标选取数据:¶

df['open'],df.open

以上两个语句是等效的,都是返回 df 名称为 open 列的数据,返回的为一个 Series。

df[0:3], df['2016-07-05':'2016-07-08']

下标索引选取的是 DataFrame 的记录,与 List 相同 DataFrame 的下标也是从0开始,区间索引的话,为一个左闭右开的区间,即[0:3]选取的为0-2三条记录。

与此等价,还可以用起始的索引名称和结束索引名称选取数据,如:df['a':'b']。有一点需要注意的是使用起始索引名称和结束索引名称时,也会包含结束索引的数据。具体看下方示例:

以上两种方式返回的都是DataFrame。

选择一列数据:

df['open']
2016-07-01    8.44
2016-07-04    8.44
2016-07-05    8.54
2016-07-06    8.54
2016-07-07    8.53
2016-07-08    8.53
2016-07-11    8.49
2016-07-12    8.49
2016-07-13    8.62
2016-07-14    8.71
2016-07-15    8.69
2016-07-18    8.73
2016-07-19    8.78
2016-07-20    8.70
Name: open, dtype: float64

选择多列数据:

df[['open','close']]
open close
2016-07-01 8.44 8.46
2016-07-04 8.44 8.55
2016-07-05 8.54 8.55
2016-07-06 8.54 8.53
2016-07-07 8.53 8.52
2016-07-08 8.53 8.49
2016-07-11 8.49 8.49
2016-07-12 8.49 8.62
2016-07-13 8.62 8.73
2016-07-14 8.71 8.68
2016-07-15 8.69 8.73
2016-07-18 8.73 8.78
2016-07-19 8.78 8.71
2016-07-20 8.70 8.70

选择多行:

df[0:3]
open high low close
2016-07-01 8.44 8.48 8.43 8.46
2016-07-04 8.44 8.60 8.42 8.55
2016-07-05 8.54 8.57 8.51 8.55

或者按 index 选取:

df['2016-07-05':'2016-07-08']
open high low close
2016-07-05 8.54 8.57 8.51 8.55
2016-07-06 8.54 8.56 8.50 8.53
2016-07-07 8.53 8.54 8.49 8.52
2016-07-08 8.53 8.53 8.48 8.49

2.3.2 使用标签选取数据:¶

df.loc[行标签,列标签]

df.loc['a':'b'] #选取 a到b 行数据

df.loc[:,'open'] #选取 open 列的数据

df.loc 的第一个参数是行标签,第二个参数为列标签(可选参数,默认为所有列标签),两个参数既可以是列表也可以是单个字符,如果两个参数都为列表则返回的是 DataFrame,否则,则为 Series。

PS:loc为location的缩写。

df.loc['2016-07-05','open']
8.5399999999999991
df.loc['2016-07-05':'2016-07-08']
open high low close
2016-07-05 8.54 8.57 8.51 8.55
2016-07-06 8.54 8.56 8.50 8.53
2016-07-07 8.53 8.54 8.49 8.52
2016-07-08 8.53 8.53 8.48 8.49
df.loc[:, 'open']
2016-07-01    8.44
2016-07-04    8.44
2016-07-05    8.54
2016-07-06    8.54
2016-07-07    8.53
2016-07-08    8.53
2016-07-11    8.49
2016-07-12    8.49
2016-07-13    8.62
2016-07-14    8.71
2016-07-15    8.69
2016-07-18    8.73
2016-07-19    8.78
2016-07-20    8.70
Name: open, dtype: float64
df.loc['2016-07-05':'2016-07-08','open']
2016-07-05    8.54
2016-07-06    8.54
2016-07-07    8.53
2016-07-08    8.53
Name: open, dtype: float64

2.3.3. 使用位置选取数据:¶

df.iloc[行位置,列位置]

df.iloc[1,1] #选取第二行,第二列的值,返回的为单个值

df.iloc[[0,2],:] #选取第一行及第三行的数据

df.iloc[0:2,:] #选取第一行到第三行(不包含)的数据

df.iloc[:,1] #选取所有记录的第二列的值,返回的为一个Series

df.iloc[1,:] #选取第一行数据,返回的为一个Series

PS:iloc 则为 integer & location 的缩写

df
open high low close
2016-07-01 8.44 8.48 8.43 8.46
2016-07-04 8.44 8.60 8.42 8.55
2016-07-05 8.54 8.57 8.51 8.55
2016-07-06 8.54 8.56 8.50 8.53
2016-07-07 8.53 8.54 8.49 8.52
2016-07-08 8.53 8.53 8.48 8.49
2016-07-11 8.49 8.53 8.49 8.49
2016-07-12 8.49 8.63 8.49 8.62
2016-07-13 8.62 8.79 8.60 8.73
2016-07-14 8.71 8.74 8.65 8.68
2016-07-15 8.69 8.74 8.65 8.73
2016-07-18 8.73 8.82 8.71 8.78
2016-07-19 8.78 8.79 8.69 8.71
2016-07-20 8.70 8.73 8.69 8.70
df.iloc[1,1] # 选取第二行,第二列的值,返回的为单个值
8.5999999999999996
df.iloc[[0,2],:] # 选取第一行及第三行的数据
open high low close
2016-07-01 8.44 8.48 8.43 8.46
2016-07-05 8.54 8.57 8.51 8.55
df.iloc[0:2,:] # 选取第一行到第三行(不包含)的数据
open high low close
2016-07-01 8.44 8.48 8.43 8.46
2016-07-04 8.44 8.60 8.42 8.55
df.iloc[:,1] # 选取所有记录的第二列的值,返回的为一个Series
2016-07-01    8.48
2016-07-04    8.60
2016-07-05    8.57
2016-07-06    8.56
2016-07-07    8.54
2016-07-08    8.53
2016-07-11    8.53
2016-07-12    8.63
2016-07-13    8.79
2016-07-14    8.74
2016-07-15    8.74
2016-07-18    8.82
2016-07-19    8.79
2016-07-20    8.73
Name: high, dtype: float64
df.iloc[1,:] # 选取第二行数据,返回的为一个Series
open     8.44
high     8.60
low      8.42
close    8.55
Name: 2016-07-04 00:00:00, dtype: float64

2.3.4. 更广义的切片方式是使用.ix,它自动根据给到的索引类型判断是使用位置还是标签进行切片¶

df.ix[1,1]

df.ix['a':'b']

df
open high low close
2016-07-01 8.44 8.48 8.43 8.46
2016-07-04 8.44 8.60 8.42 8.55
2016-07-05 8.54 8.57 8.51 8.55
2016-07-06 8.54 8.56 8.50 8.53
2016-07-07 8.53 8.54 8.49 8.52
2016-07-08 8.53 8.53 8.48 8.49
2016-07-11 8.49 8.53 8.49 8.49
2016-07-12 8.49 8.63 8.49 8.62
2016-07-13 8.62 8.79 8.60 8.73
2016-07-14 8.71 8.74 8.65 8.68
2016-07-15 8.69 8.74 8.65 8.73
2016-07-18 8.73 8.82 8.71 8.78
2016-07-19 8.78 8.79 8.69 8.71
2016-07-20 8.70 8.73 8.69 8.70
df.ix[1,1]
8.5999999999999996
df.ix['2016-07-01':'2016-07-05']
open high low close
2016-07-01 8.44 8.48 8.43 8.46
2016-07-04 8.44 8.60 8.42 8.55
2016-07-05 8.54 8.57 8.51 8.55
df.ix['2016-07-05','open']
8.5399999999999991
df.ix[1,'open']
8.4399999999999995
df.ix['2016-07-01',0]
8.4399999999999995

2.3.5 通过逻辑指针进行数据切片:¶

df[逻辑条件]

df[df.one >= 2] #单个逻辑条件

df[(df.one >=1 ) & (df.one < 3) ] #多个逻辑条件组合

df
open high low close
2016-07-01 8.44 8.48 8.43 8.46
2016-07-04 8.44 8.60 8.42 8.55
2016-07-05 8.54 8.57 8.51 8.55
2016-07-06 8.54 8.56 8.50 8.53
2016-07-07 8.53 8.54 8.49 8.52
2016-07-08 8.53 8.53 8.48 8.49
2016-07-11 8.49 8.53 8.49 8.49
2016-07-12 8.49 8.63 8.49 8.62
2016-07-13 8.62 8.79 8.60 8.73
2016-07-14 8.71 8.74 8.65 8.68
2016-07-15 8.69 8.74 8.65 8.73
2016-07-18 8.73 8.82 8.71 8.78
2016-07-19 8.78 8.79 8.69 8.71
2016-07-20 8.70 8.73 8.69 8.70
# 筛选出 open 大于 8.8 的数据
df[df.open > 8.8]
open high low close
# 筛选出 open 大于 8.8 的数据,并且 close 小于 9.0 的数据
df[(df.open > 8.8) & (df.close < 9.0)]
open high low close

使用 条件过来更改数据。

df[df>9.0]
open high low close
2016-07-01 NaN NaN NaN NaN
2016-07-04 NaN NaN NaN NaN
2016-07-05 NaN NaN NaN NaN
2016-07-06 NaN NaN NaN NaN
2016-07-07 NaN NaN NaN NaN
2016-07-08 NaN NaN NaN NaN
2016-07-11 NaN NaN NaN NaN
2016-07-12 NaN NaN NaN NaN
2016-07-13 NaN NaN NaN NaN
2016-07-14 NaN NaN NaN NaN
2016-07-15 NaN NaN NaN NaN
2016-07-18 NaN NaN NaN NaN
2016-07-19 NaN NaN NaN NaN
2016-07-20 NaN NaN NaN NaN

观察可以发现,df 中小于 9 的数都变为 NaN。

下面我们就把大于 9 的数赋值为0.

df[df > 9.0] = 0
df
open high low close
2016-07-01 8.44 8.48 8.43 8.46
2016-07-04 8.44 8.60 8.42 8.55
2016-07-05 8.54 8.57 8.51 8.55
2016-07-06 8.54 8.56 8.50 8.53
2016-07-07 8.53 8.54 8.49 8.52
2016-07-08 8.53 8.53 8.48 8.49
2016-07-11 8.49 8.53 8.49 8.49
2016-07-12 8.49 8.63 8.49 8.62
2016-07-13 8.62 8.79 8.60 8.73
2016-07-14 8.71 8.74 8.65 8.68
2016-07-15 8.69 8.74 8.65 8.73
2016-07-18 8.73 8.82 8.71 8.78
2016-07-19 8.78 8.79 8.69 8.71
2016-07-20 8.70 8.73 8.69 8.70

发现大于 9 的数都被替换为了0.

接下来教大家使用isin()方法来过滤在指定列中的数据:

# 选取 high 列中数为 0 和 9 的数。
df[df['high'].isin([0.00,9.00])]
open high low close

3. Panel¶

平台get_price,如果是多支股票, 则返回pandas.Panel对象。更多内容请参考http://pandas.pydata.org/pandas-docs/stable/api.html#panel

可通过 panel[列标,行标,股票代码] 获取数据.

panel = get_price(['000001.XSHE','000002.XSHE'],start_date='2016-07-12', end_date='2016-07-15', frequency='daily', fields=['open','high','low','close'])
panel
<class 'pandas.core.panel.Panel'>
Dimensions: 4 (items) x 4 (major_axis) x 2 (minor_axis)
Items axis: close to open
Major_axis axis: 2016-07-12 00:00:00 to 2016-07-15 00:00:00
Minor_axis axis: 000001.XSHE to 000002.XSHE

由打印的结果可以看出:

  • 列标(Items axis: close to open)
  • 行标(Major_axis axis: 2016-07-12 00:00:00 to 2016-07-15 00:00:00)
  • 股票代码(Minor_axis axis: 000001.XSHE to 000002.XSHE)
# 取出 'open'数据
panel['open',:,:]
000001.XSHE 000002.XSHE
2016-07-12 8.49 16.32
2016-07-13 8.62 16.08
2016-07-14 8.71 16.20
2016-07-15 8.69 15.99
# 取出 '2016-07-15'数据
panel[:,'2016-07-15',:]
close high low open
000001.XSHE 8.73 8.74 8.65 8.69
000002.XSHE 15.98 16.12 15.95 15.99
# 取出 000001 的 DataFrame 数据
panel[:,:,'000001.XSHE']
close high low open
2016-07-12 8.62 8.63 8.49 8.49
2016-07-13 8.73 8.79 8.60 8.62
2016-07-14 8.68 8.74 8.65 8.71
2016-07-15 8.73 8.74 8.65 8.69

Panel 操作与 DataFrame 基本相同,下节会为大家讲解 DataFrame 的数据处理与规整。

 
 

全部回复

0/140

量化课程

    移动端课程