python数据分析之pandas包
2017-05-08 本文已影响142人
Abem
Pandas是一个开源的Python数据分析库。pandas具有强大的数据分析功能,这不仅体现在其数据分析功能的完备性,更体现在其对于大数据运算的速度,它可以将几百MB数据以高效的向量化格式加载到内存,在短时间内完成1亿次浮点计算。纽约大学柯朗研究所博士后Chris Stucchio在文章《别老扯什么Hadoop了,你的数据根本不够大》中指出:只有在超过5TB数据量的规模下,Hadoop才是一个合理的技术选择。可见,在数据量为几百MB的情况下,用pandas进行处理无疑是一个明智的选择。
值得一提的是,pandas能够轻松完成SQL、MySQL等数据库中的对数据库的查找或表连接等功能,对于大量数据,只需耐心花些时间完成上传数据工作,其后的数据处理速度完全不亚于数据库的处理速度,而且能够实现更高的灵活性。
Pandas把结构化数据分为了三类:
1. Series
1维序列,可视作为没有column名的、只有一个column的DataFrame;
2. DataFrame
同Spark SQL中的DataFrame一样,其概念来自于R语言,为多column并schema化的2维结构化数据,可视作为Series的容器(container);
3. Panel
为3维的结构化数据,可视作为DataFrame的容器。
下面我们将通过Python中的pandas包完成常见的数据分析任务:
相关系数和协方差
import pandas.io.data as web
from pandas import DataFrame,Series
import pandas as pd
import numpy as np
all_data = {}
for tricker in ['AAPL','IBM','MSFT','GOOG']:
all_data[tricker] = web.get_data_yahoo(tricker,'1/1/2000','1/1/2010')
price = DataFrame({tic:data['Adj Close']
for tic,data in all_data.iteritems()})
volume = DataFrame({tic:data['Volume']
for tic,data in all_data.iteritems()})
#价格的百分比变化
returns = price.pct_change()
print returns.tail()
#计算相关系数和协方差
returns.MSFT.corr(returns.IBM)
returns.MSFT.cov(returns.IBM)
returns.corr()
returns.cov()
returns.corrwith(returns.IBM)
#计算price和volume之间的相关系数
returns.corrwith(volume)
唯一值、值计数及成员资格
obj = Series(['c','a','d','a','a','b','c','v','g'])
uniques = obj.unique()
uniques
obj.value_counts()
pd.value_counts(obj.values,sort=False)
mask = obj.isin(['b','c'])
mask
obj[mask]
处理缺失数据
string_data = Series(['a','c','a','d','a','a','b','c',np.nan,'a','b','c','v','g'])
string_data.isnull()
#python内置的None也会被当作缺失值处理
string_data[0] = None
string_data.isnull()
#series对象过滤掉缺失数据
string_data.dropna()
#or
string_data[string_data.notnull()]
#DataFrame对象过滤掉缺失数据
data = DataFrame([[np.nan,2,3],[np.nan,4,5],[4,5,6],[np.nan,np.nan,np.nan]])
#过滤含有nan的行
data
data.dropna()
#过滤全为nan的行
data.dropna(how='all')
#时间序列数据
df = DataFrame(np.random.randn(7,3))
df.ix[:4,1] = np.nan
df.ix[:2,2] = np.nan
df
df.dropna(thresh=2)
'''填充缺失数据'''
df.fillna(0)
df.fillna({1:0.5,3:-1,2:0.1})
#fillna默认返回新对象,但也可以对现有对象进行就地修改
_ = df.fillna({1:0.5},inplace=True)
df
#对reindex有效的插值方法也可以用于fillna
df.fillna(method='ffill')
#限制可以连续填充的最大数量
df.fillna(method='ffill',limit=2)
#用平均值或中值进行插值
data.fillna(data.mean())
层次化索引
#Series数据层次化索引
data1 = Series(np.random.randn(10),
index=[['a','a','a','b','b','b','c','c','d','d'],
[1,2,3,1,2,3,1,2,2,3]])
data1
data1.index
data1['b']
data1['b':'d']
data1.ix[['b','d']]
data1[:,2]
数据透视生成
data1.unstack()
#unstack的逆运算是stack()
data1.unstack().stack()
#DataFrame分层索引
frame = DataFrame(np.arange(12).reshape((4,3)),
index = [['a','a','b','b'],[1,2,1,2]],
columns = [['ohio','ohio','colorado'],
['green','red','green']])
frame
#给索引命名
frame.index.names = ['key1','key2']
#给轴标签命名
frame.columns.names = ['state','color']
frame
#分组
frame['ohio']
重排分级次序
frame.swaplevel('key1','key2')
#交换排序级别
frame.sortlevel(1)
frame.swaplevel(0,1).sortlevel(0)
根据级别汇总统计
#行汇总
frame.sum(level='key2')
#列汇总
frame.sum(level='color',axis=1)
'''使用DataFrame的列'''
frame1 = DataFrame({'a':range(7),
'b':range(7,0,-1),
'c':['one','one','one','two','two','two','two'],
'd':[0,1,2,0,1,2,3]})
列索引转为行索引
frame2 = frame1.set_index(['c','d'])
frame2
frame2 = frame1.set_index(['c','d'],drop=False)
frame2
#set_index 的逆运算 reset_index
frame2.reset_index()
import numpy as np
import pandas as pd
from pandas import DataFrame,Series
读取文件
#读取文本格式的数据
pd.read_csv('',nrows=1)
#读取带分隔符的数据,如txt等,sep或delimiter为分隔符或正则表达式,Sep默认分隔符为空格,而delimiter默认分隔符为逗号
pd.table('',sep=' ')
#使用pandas默认列名
pd.read_csv('',header=None)
#自定义列名
pd.read_csv('',names=['a','b','c'])
#指定某一列为索引
pd.read_csv('',names=names,index_col='a')
导出文件
#为空字符串标记为NULL
data.to_csv('',na_rep='NULL')
数据库风格的DataFrame合并
df1 = DataFrame({'key':['b','b','a','c','a','a','b'],
'data1':range(7)})
df2 = DataFrame({'key':['a','b','d'],
'data1':range(3)})
#将df2中的数据对应到df1上,如果没有则删掉
pd.merge(df1,df2,on='key')
#如果键不同,则分别进行指定
pd.merge(df1,df2,left_on='key1',right_on='key2')
#外链接
df1
df2
pd.merge(df1,df2,on='key',how='outer')
pd.merge(df1,df2,on='key',how='left')
pd.merge(df1,df2,on='key',how='inner')
#多键合并
left = DataFrame({'key1':['foo','foo','bar'],
'key2':['one','two','one'],
'lval':[1,2,3]})
right = DataFrame({'key1':['foo','foo','bar','bar'],
'key2':['one','one','one','two'],
'lval':[4,5,6,7]})
left
right
pd.merge(left,right,on=['key1','key2'],how='outer')
#注意,在进行一列连接时,DataFrame对象中的索引会被丢弃掉
pd.merge(left,right,on='key1')
#suffixes附加到左右两个DataFrame对象的重叠列名上的字符串
pd.merge(left,right,on='key1')
pd.merge(left,right,on='key1',suffixes=('_left','_right'))
#how默认为innner,可选inner,outer,left,right
#有时候DataFrame中的连接键位于其索引中,此时用left_index=True以说明索引键应被用作连接键
left1 = DataFrame({'key':['a','b','s','a','b','a','b'],
'value1':[1,2,3,1,2,3,1]})
right1 = DataFrame({'vallue2':[4,5]},index=['a','b'])
pd.merge(left1,right1,left_on='key',right_index=True)
pd.merge(left1,right1,left_on='key',right_index=True,how='outer')
#对层次化索引的数据
lefth = DataFrame({'key1':['ohio','ohio','ohio','nevada','nevada'],
'key2':[2000,2001,2002,2001,2002],
'data':np.arange(5.)})
righth = DataFrame(np.arange(12).reshape((6,2)),
index=[['nevada','nevada','ohio','ohio','ohio','ohio'],
[2001,2000,2000,2000,2001,2002]],
columns=['event1','event2'])
lefth
righth
pd.merge(lefth,righth,left_on=['key1','key2'],right_index=True)
pd.merge(lefth,righth,left_on=['key1','key2'],right_index=True,how='outer')
#同时使用合并双方的索引也没问题
left2 = DataFrame({'ohio':[1,4,2,6,4,7,8],
'nevada':[2,4,5,2,6,6,4]},
index=['a','s','c','a','b','c','c'])
right2 = DataFrame({'Missouri':[10,11,35],
'alabama':[45,34,56]},
index=['c','a','e'])
pd.merge(left2,right2,left_index=True,right_index=True)
pd.merge(left2,right2,left_index=True,right_index=True,how='outer')
#外连接也可以写成
left2.join(right2,how='outer')
#join方法也支持DataFrame的索引跟调用者DataFrame某个列之间的连接
left1.join(right1,on='key')
#索引合并也可以传入另一个DataFrame
#another和right2的行数相等
left2.join([right2,another])
#注意,在进行左链接时,右表的用来链接的键应唯一,否则链接后的表数据条数会多于原来的左表
pandas知识体系图
pandas知识体系图注:本文来源于《用Python进行数据分析》学习笔记,如有错漏,恳请指正~