经济学中的定量分析python-ag凯发k8国际
pandas是python的一个数据分析包,最初由aqr capital management于2008年4月开发,并于2009年底开源出来,目前由专注于python数据包开发的pydata开发team继续开发和维护,属于pydata项目的一部分。pandas最初被作为金融数据分析工具而开发出来,因此,pandas为时间序列分析提供了很好的支持。 pandas的名称来自于面板数据(panel data)和python数据分析(data analysis)。panel data是经济学中关于多维数据集的一个术语,在pandas中也提供了panel的数据类型。 这篇文章会介绍一些pandas的基本知识,偷了些懒其中采用的例子大部分会来自官方的10分钟学pandas。我会加上个人的理解,帮助大家记忆和学习。
pandas中的数据结构
series:一维数组,与numpy中的一维array类似。二者与python基本的数据结构list也很相近,其区别是:list中的元素可以是不同的数据类型,而array和series中则只允许存储相同的数据类型,这样可以更有效的使用内存,提高运算效率。
time- series:以时间为索引的series。
dataframe:二维的表格型数据结构。很多功能与r中的data.frame类似。可以将dataframe理解为series的容器。以下的内容主要以dataframe为主。
panel :三维的数组,可以理解为dataframe的容器。
创建dataframe
首先引入pandas及numpy:
import pandas as pd
import numpy as np
官方推荐的缩写形式为pd,你可以选择其他任意的名称。 dataframe是二维的数据结构,其本质是series的容器,因此,dataframe可以包含一个索引以及与这些索引联合在一起的series,由于一个series中的数据类型是相同的,而不同series的数据结构可以不同。因此对于dataframe来说,每一列的数据结构都是相同的,而不同的列之间则可以是不同的数据结构。或者以数据库进行类比,dataframe中的每一行是一个记录,名称为index的一个元素,而每一列则为一个字段,是这个记录的一个属性。 创建dataframe有多种方式:
以字典的字典或series的字典的结构构建dataframe,这时候的最外面字典对应的是dataframe的列,内嵌的字典及series则是其中每个值。
d = {'one' : pd.series([1., 2., 3.], index=['a', 'b', 'c']),'two' : pd.series([1., 2., 3., 4.], index=['a', 'b', 'c', 'd'])}
df = pd.dataframe(d)
可以看到d是一个字典,其中one的值为series有3个值,而two为series有4个值。由d构建的为一个4行2列的dataframe。其中one只有3个值,因此d行one列为nan(not a number)--pandas默认的缺失值标记。
从列表的字典构建dataframe,其中嵌套的每个列表(list)代表的是一个列,字典的名字则是列标签。这里要注意的是每个列表中的元素数量应该相同。否则会报错:
valueerror: arrays must all be same length
从字典的列表构建dataframe,其中每个字典代表的是每条记录(dataframe中的一行),字典中每个值对应的是这条记录的相关属性。
d = [{'one' : 1,'two':1},{'one' : 2,'two' : 2},{'one' : 3,'two' : 3},{'two' : 4}]
df = pd.dataframe(d,index=['a','b','c','d'],columns=['one','two'])
df.index.name='index'
以上的语句与以series的字典形式创建的dataframe相同,只是思路略有不同,一个是以列为单位构建,将所有记录的不同属性转化为多个series,行标签冗余,另一个是以行为单位构建,将每条记录转化为一个字典,列标签冗余。使用这种方式,如果不通过columns指定列的顺序,那么列的顺序会是随机的。
个人经验是对于从一些已经结构化的数据转化为dataframe似乎前者更方便,而对于一些需要自己结构化的数据(比如解析log文件,特别是针对较大数据量时),似乎后者更方便。创建了dataframe后可以通过index.name属性为dataframe的索引指定名称。
dataframe转换为其他类型
df.to_dict(outtype='dict')
outtype的参数为‘dict’、‘list’、‘series’和‘records’。 dict返回的是dict of dict;list返回的是列表的字典;series返回的是序列的字典;records返回的是字典的列表
查看数据
head和tail方法可以显示dataframe前n条和后n条记录,n为对应的参数,默认值为5。这通常是拿到dataframe后的第一个命令,可以方便的了解数据内容和含义。
df.head()
onetwo
index
a
1
1
b
2
2
c
3
3
d
nan
4
4 rows × 2 columns
r中的对应函数:
head(df)
df.tail()
onetwo
index
a
1
1
b
2
2
c
3
3
d
nan
4
4 rows × 2 columns
index(行)和columns(列)属性,可以获得dataframe的行和列的标签。这也是了解数据内容和含义的重要步骤。
df.index
index([u'a', u'b', u'c', u'd'], dtype='object')
查看字段名
df.columns
index([u'one', u'two'], dtype='object')
decribe方法可以计算各个列的基本描述统计值。包含计数,平均数,标准差,最大值,最小值及4分位差。
df.describe()
onetwo
count
3.0
4.000000
mean
2.0
2.500000
std
1.0
1.290994
min
1.0
1.000000
25%
1.5
1.750000
50%
2.0
2.500000
75%
2.5
3.250000
max
3.0
4.000000
8 rows × 2 columns
r中的对应函数:
summary(df)
行列转置
df.t
indexabcd
one
1
2
3
nan
two
1
2
3
4
2 rows × 4 columns
排序
dataframe提供了多种排序方式。
df.sort_index(axis=1, ascending=false)
sort_index可以以轴的标签进行排序。axis是指用于排序的轴,可选的值有0和1,默认为0即行标签(y轴),1为按照列标签排序。 ascending是排序方式,默认为true即降序排列。
df.sort(columns='two')
df.sort(columns=['one','two'],ascending=[0,1])
dataframe也提供按照指定列进行排序,可以仅指定一个列作为排序标准(以单独列名作为columns的参数),也可以进行多重排序(columns的参数为一个列名的list,列名的出现顺序决定排序中的优先级),在多重排序中ascending参数也为一个list,分别与columns中的list元素对应。
读写数据
dataframe可以方便的读写数据文件,最常见的文件为csv或excel。pandas读写excel文件需要openpyxl(excel 2007), xlrd/xlwt(excel 2003)。
从csv中读取数据:
df = pd.read_csv('foo.csv')
r中的对应函数:
df = read.csv('foo.csv')
将dataframe写入csv:
df.to_csv('foo.csv')
r中的对应函数:
df.to.csv('foo.csv')
从excel中读取数据:
xls = excelfile('foo.xlsx')
xls.parse('sheet1', index_col=none, na_values=['na'])
先定义一个excel文件,用xls.parse解析sheet1的内容,index_col用于指定index列,na_values定义缺失值的标识。
将dataframe写入excel文件:
df.to_excel('foo.xlsx', sheet_name='sheet1')
默认的sheet为sheet1,也可以指定其他sheet名。
数据切片
通过下标选取数据:
df['one']
df.one
以上两个语句是等效的,都是返回df名称为one列的数据,返回的为一个series。
df[0:3]
df[0]
下标索引选取的是dataframe的记录,与list相同dataframe的下标也是从0开始,区间索引的话,为一个左闭右开的区间,即[0:3]选取的为1-3三条记录。与此等价,还可以用起始的索引名称和结束索引名称选取数据:
df['a':'b']
有一点需要注意的是使用起始索引名称和结束索引名称时,也会包含结束索引的数据。以上两种方式返回的都是dataframe。
使用标签选取数据:
df.loc[行标签,列标签]
df.loc['a':'b']#选取ab两行数据
df.loc[:,'one']#选取one列的数据
df.loc的第一个参数是行标签,第二个参数为列标签(可选参数,默认为所有列标签),两个参数既可以是列表也可以是单个字符,如果两个参数都为列表则返回的是dataframe,否则,则为series。
使用位置选取数据:
df.iloc[行位置,列位置]
df.iloc[1,1]#选取第二行,第二列的值,返回的为单个值
df.iloc[0,2],:]#选取第一行及第三行的数据
df.iloc[0:2,:]#选取第一行到第三行(不包含)的数据
df.iloc[:,1]#选取所有记录的第一列的值,返回的为一个series
df.iloc[1,:]#选取第一行数据,返回的为一个series
ps:loc为location的缩写,iloc则为integer & location的缩写
更广义的切片方式是使用.ix,它自动根据你给到的索引类型判断是使用位置还是标签进行切片
df.ix[1,1]
df.ix['a':'b']
通过逻辑指针进行数据切片:
df[逻辑条件]
df[df.one >= 2]#单个逻辑条件
df[(df.one >=1 ) & (df.one < 3) ]#多个逻辑条件组合
这种方式获得的数据切片都是dataframe。
基本运算
pandas支持基本的运算及向量化运算。
df.mean()#计算列的平均值,参数为轴,可选值为0或1.默认为0,即按照列运算
df.sum(1)#计算行的和
df.apply(lambda x: x.max() - x.min())#将一个函数应用到dataframe的每一列,这里使用的是匿名lambda函数,与r中apply函数类似
设置索引
df.set_index('one')
重命名列
df.rename(columns={u'one':'1'}, inplace=true)
查看每个列的数据类型
df.dtypes
r中的对应函数:
str(df)
查看最大值/最小值
pd.series.max()
pd.series.idxmax()
重设索引
df.reset_index(inplace=true)
改变数据类型
df['a'].astype(float)
计算series每个值的频率
df['a'].value_counts()
r的对应函数:
table(df['a'])
字符方法
pandas提供许多向量化的字符操作,你可以在str属性中找到它们
s.str.lower()
s.str.len()
s.str.contains(pattern)
dataframe的合并
contact:
ds = [{'one' : 4,'two':2},{'one' : 5,'two' : 3},{'one' : 6,'two' : 4},{'two' : 7,'three':10}]
dfs = pd.dataframe(ds,index=['e','f','g','h'])
##构建一个新的dataframe,dfs
df_t=pd.concat([df,dfs])#合并两个dataframe
merge(类似sql中的join操作):
left = pd.dataframe({'key': ['foo1', 'foo2'], 'lval': [1, 2]})
right = pd.dataframe({'key': ['foo1', 'foo2'], 'rval': [4, 5]})
#构建了两个dataframe
pd.merge(left, right, on='key')#按照key列将两个dataframe join在一起
dataframe中的group by:
df = pd.dataframe({'a' : ['foo', 'bar', 'foo', 'bar','foo', 'bar', 'foo', 'foo'],
'b' : ['one', 'one', 'two', 'three','two', 'two', 'one', 'three'],
'c' :randn(8), 'd' : randn(8)});
df.groupby('a').sum()#按照a列的值分组求和
df.groupby(['a','b']).sum()##按照a、b两列的值分组求和
对应r函数:
tapply()
在实际应用中,先定义groups,然后再对不同的指标指定不同计算方式。
groups = df.groupby('a')#按照a列的值分组求和
groups['b'].sum()##按照a列的值分组求b组和
groups['b'].count()##按照a列的值分组b组计数
默认会以groupby的值作为索引,如果不将这些值作为索引,则需要使用as_index=false
df.groupby(['a','b'], as_index=false).sum()
构建透视表
使用pivot_table和crosstab都可以创建数据透视表
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)})
pd.pivot_table(df, values = 'd', rows = ['a', 'b'], cols = ['c'])#以a、b为行标签,以c为列标签将d列的值汇总求和
pd.crosstab(rows = ['a', 'b'], cols = ['c'], values = 'd')#以a、b为行标签,以c为列标签将d列的值汇总求和
时间序列分析
时间序列也是pandas的一个特色。时间序列在pandas中就是以timestamp为索引的series。
pandas提供to_datetime方法将代表时间的字符转化为timestamp对象:
s = '2013-09-16 21:00:00'
ts = pd.to_datetime(s)
有时我们需要处理时区问题:
ts=pd.to_datetime(s,utc=true).tz_convert('asia/shanghai')
构建一个时间序列:
rng = pd.date_range('1/1/2012', periods=5, freq='m')
ts = pd.series(randn(len(rng)), index=rng)
pandas提供resample方法对时间序列的时间粒度进行调整:
ts_h=ts.resample('h', how='count')#m,5min,1s
以上是将时间序列调整为小时,还可以支持月(m),分钟(min)甚至秒(s)等。
画图
pandas也支持一定的绘图功能,需要安装matplot模块。
比如前面创建的时间序列,通过plot()就可以绘制出折线图,也可以使用hist()命令绘制频率分布的直方图。
关于panda作图,请查看另一篇博文:用pandas作图
以上是关于pandas的简单介绍,其实除了pandas之外,python还提供了多个科学计算包,比如numpy,scipy,以及数据挖掘的包:scikit learn,orage,nltk等,感兴趣的同学可以了解一下。
总结
以上是ag凯发k8国际为你收集整理的经济学中的定量分析python_(转)python中的结构化数据分析利器-pandas简介的全部内容,希望文章能够帮你解决所遇到的问题。
- 上一篇: vue中引用js_从js中的内存管理说起
- 下一篇: