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

# 首先导入库
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

获取 Series 的索引:

s.index

由于 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)
df = pd.DataFrame(np.random.randn(6,4),index=dates,columns=list('ABCD'))

2.2 查看数据 

我们以聚宽平台获取的数据为例:

from jqdatasdk import *

auth("username", "password")
# print(is_auth())

zgpa = get_price("603138.XSHG", start_date="2020-05-01", end_date="2020-5-14", frequency="daily",
                 fields=["open", "high", "low", "close"])
# print(zgpa)  # 一个DateFrame对象
# print(zgpa.head())  # 获取前几行数据
# print(zgpa.tail())   # 获取最后几行数据
# print(zgpa.index)  # 获取索引
# print(zgpa.columns)  # 获列
# print(zgpa.values)   # 获取值
# print(zgpa.describe())  # 获取汇总数据
# print(zgpa.T)  # 转置
# print(zgpa.sort_values(by="close"))  # 对某一列排序,不改变原DateFrame对象

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。
# print(zgpa["open"])  # 选择open列的数据
# print(zgpa.low)  # 选择low列的数据
# print(zgpa[["open", "close"]])  # 选择多列数据
# print(zgpa[1:3])  # 选择多行数据
# print(zgpa[0:3])  # 选择多行数据
# print(zgpa["2020-05-08": "2020-05-13"])  # 按照index选取区间数据

2.3.2 使用标签选取数据:

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

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

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

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

PS:loc为location的缩写。
# 使用标签选取数据
# print(zgpa.loc["2020-05-08", "open"])  # 2020-05-08 行中的open列数据,返回series对象
# print(zgpa.loc["2020-05-08", ])  # 2020-05-08 行中的所有列的数据
# print(type(zgpa.loc["2020-05-08", ["close", "open"]]))  # 2020-05-08 行中的所有列的数据
# print(zgpa.loc["2020-05-08": "2020-05-13"])  # 2020-05-08 至 2020-05-13 行中的所有列的数据, 返回一个DateFrame对象

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 的缩写
#  使用位置选取数据
# print(zgpa.iloc[1, 2])  # 获取第二行,第三列的数据
# print(zgpa.iloc[1:5, ])  # 获取第2行至第5行的所有列数据
# print(zgpa.iloc[1:5, :])  # 获取第2行至第5行的所有列数据
# print(zgpa.iloc[:, 2])  # 获取所有行的第三列数据, 返回的为一个Series
# print(zgpa.iloc[1, :])  # 获取第一行的所有数据, 返回的为一个Series

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

df[逻辑条件]

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

df[(df.one >=1 ) & (df.one < 3) ] #多个逻辑条件组合
# 通过逻辑进行数据切片
# print(zgpa[zgpa.close < 21])  # 获取收盘价大于21的天数 数据
# print(zgpa[(zgpa.open > 20) & (zgpa.close < 21)])  # 获取开盘价大于20,并且收盘价小于21的天数数据
# print(zgpa[(zgpa.open > 20) | (zgpa.close < 21)])  # 获取开盘价大于20,或者收盘价小于21的天数数据

使用isin方法过滤数据

# print(zgpa["close"].isin([20.80, ]))  # 获取close列中,值是否有符合20.80的数,不符合返回false
# print(zgpa[zgpa["close"].isin([20.80, ])])   # 获取close列中,值为20.80的数

pandas库之数据处理与规整

上一节我们介绍了 DataFrame 的数据查看与选择

本节主要讲解 DataFrame 的数据处理,包括缺失数据处理、函数的应用和映射、数据规整、分组等。

# 首先导入库
import pandas as pd
# 获取平安银行近几个工作日的开盘价、最高价、最低价、收盘价。
df = get_price('000001.XSHE',start_date='2016-07-01', end_date='2016-07-20', frequency='daily', fields=['open','high','low','close'])
df[df > 9.0] = NaN
df

1 缺失数据处理

1. 1去掉包含缺失值的行:

df.dropna()

1.2 对缺失值进行填充:

df.fillna(value=0)

1.3 判断数据是否为nan,并进行布尔填充:

pd.isnull(df)

2 函数的应用和映射

df.mean()#列计算平均值
open     8.831538
high     8.863636
low      8.812857
close    8.855385
dtype: float64
df.mean(1)#行计算平均值
2016-07-01    8.7025
2016-07-04    8.7575
2016-07-05    8.8025
2016-07-06    8.7925
2016-07-07    8.7775展开输出 ↓    
2016-07-08    8.7625
2016-07-11    8.7575
2016-07-12    8.8150
2016-07-13    8.9100
2016-07-14    8.9550
2016-07-15    8.9625
2016-07-18    8.9800
2016-07-19    8.9600
2016-07-20    8.9650
dtype: float64
df.mean(axis = 1,skipna = False) # skipna参数默认是 True 表示排除缺失值
2016-07-01    8.7025
2016-07-04    8.7575
2016-07-05    8.8025
2016-07-06    8.7925
2016-07-07    8.7775展开输出 ↓    
2016-07-08    8.7625
2016-07-11    8.7575
2016-07-12    8.8150
2016-07-13       NaN
2016-07-14    8.9550
2016-07-15    8.9625
2016-07-18       NaN
2016-07-19       NaN
2016-07-20    8.9650
dtype: float64
df.sort_index()#行名字排序
 
df.sort_index(axis=1)#列名字排序
# 数据默认是按升序排序的,也可以降序排序
df.sort_index(axis=1,ascending = False)

常用的方法如上所介绍们,还要其他许多,可自行学习,下面罗列了一些,可供参考:

count 非na值的数量

describe 针对Series或个DataFrame列计算汇总统计

min、max 计算最小值和最大值

argmin、argmax 计算能够获取到最大值和最小值得索引位置(整数)

idxmin、idxmax 计算能够获取到最大值和最小值得索引值

quantile 计算样本的分位数(0到1)

sum 值的总和

mean 值得平均数

median 值得算术中位数(50%分位数)

mad 根据平均值计算平均绝对离差

var 样本值的方差

std 样本值的标准差

skew 样本值得偏度(三阶矩)

kurt 样本值得峰度(四阶矩)

cumsum 样本值得累计和

cummin,cummax 样本值得累计最大值和累计最小值

cumprod 样本值得累计积

diff 计算一阶差分(对时间序列很有用)

pct_change 计算百分数变化

3 数据规整

Pandas提供了大量的方法能够轻松的对Series,DataFrame和Panel对象进行各种符合各种逻辑关系的合并操作

concat 可以沿一条轴将多个对象堆叠到一起。

append 将一行连接到一个DataFrame上

duplicated 移除重复数据

3.1 concat

df1 = get_price('000001.XSHE',start_date='2016-07-05', end_date='2016-07-08', frequency='daily', fields=['open','high','low','close'])
df1
df2 = get_price('000001.XSHE',start_date='2016-07-12', end_date='2016-07-15', frequency='daily', fields=['open','high','low','close'])
df2

纵向拼接(默认):

pd.concat([df1,df2],axis=0)

横向拼接,index对不上的会用 NaN 填充:

pd.concat([df1,df2],axis=1)

下面演示一下index 可以对上情况的横向拼接结果:

df3 = get_price('000001.XSHE',start_date='2016-07-12', end_date='2016-07-15', frequency='daily', fields=['low','close'])
df4 = get_price('000001.XSHE',start_date='2016-07-12', end_date='2016-07-15', frequency='daily', fields=['open','high'])
pd.concat([df3,df4],axis=1)

3.2 append

df1
s = df1.iloc[0]
s
open     8.80
high     8.83
low      8.77
close    8.81
Name: 2016-07-05 00:00:00, dtype: float64
df1.append(s, ignore_index=False) # ignore_index=False 表示索引不变
df1.append(s, ignore_index=True) # ignore_index=True 表示索引重置

3.3 移除重复数据duplicated

z = df1.append(s, ignore_index=False)
z

 查看重复数据:

z.duplicated()
2016-07-05    False
2016-07-06    False
2016-07-07    False
2016-07-08    False
2016-07-05     True展开输出 ↓    
dtype: bool
移除重复数据:

z.drop_duplicates()

4 分组

z.groupby('open').sum()
z.groupby(['open','close']).sum()
 
 Panel:
df9 = get_price(['000001.XSHE','000002.XSHE'],start_date='2016-07-12', end_date='2016-07-15', frequency='daily', fields=['open','high','low','close'])
df9
<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
df9[:,0,:]
df9[:,:,0]
df9[:,:,1]
df9[0,:,:]
df9.ix[:,0]
参考:聚宽
 
 
 
原文地址:https://www.cnblogs.com/aizhinong/p/12892073.html