# -*- coding: utf-8 -*-
"""
Created on Fri Feb 17 15:04:50 2017
@author: zzpp220
"""
from pandas import DataFrame,Series
from numpy import nan as NaN
import pandas as pd
import numpy as np
import pandas.io.data as web
#==============================================================================
##Series----
obj1=Series([1,23,3,5,7,8])#默认索引为整数
obj1.index=['o','t','u','h','j','l']##可以后面添加或者更改索引
obj2=Series([1,2,3,4,5,6,76],index=['a','s','f','g','h','t','d']) #创建带索引的
#print obj2.index,obj2.values,obj2[['a','s','d','g']] #通过指定一个或者一组索引选取其中相应的值
#print obj2[obj2>0]
#print obj2*2
#print np.exp(obj2)
#print obj2[obj2==76]
##因为索引和数据在Series中也是意义映射的,可以看成是有序的字典
#print 'a' in obj2,'a' in obj2.index
#print 76 in obj2,76 in obj2.values
##数据既可以通过对应的索引,也可以通过下标。所以是在字典的基础上更加有序
#print obj2[4],obj2['h']
##通过字典创建Series对象
sdata={'zx':24,'gts':25,'zf':26,'yk':18}
obj3=Series(sdata)#只传入一个字典,则obj3的索引就是原来字典的索引(原来什么顺序,现在就是什么顺序)
##传入一个字典和另给一个序列更新索引。sdata中与states相匹配的索引会被找出来并放到对应的位置上,但由于'yhl'在sdata中找不到所对应的值,会设为nan
states=['yhl','zf','gts','zx']
obj4=Series(sdata,states)
#print obj4['yhl']#nan
##use .isnull(),.notnull()
#print obj4.isnull(),pd.isnull(obj4) ##作用一样
#print obj4.notnull(),pd.notnull(obj4)
##############如何处理缺失数据################################################
#series 的一个重要功能是:在算术运算中 会自动 对齐 不同索引 的 数据
obj34=obj3+obj4
obj4.name='population'
obj4.index.name='state'
##创建dataframe
##最常用的办法是传入一个由 等长列表 组成的 字典,字典的索引就是表格的列名,索引对应的列表就相当于一条记录
#(dataframe 会默认自动加上索引index--相当于给记录标号)
data={'zx':[24,1993,604],'gts':[25,1992,930],'zf':[26,1991,807],'yk':[18,2002,314]}
##指定列的顺序
frame=DataFrame(data,columns=['zx','gts','zf','yk'])
frame.index=['age','year','mon_day']
##如果找不到列名对应的数据,默认设为nan,指定index
frame2=DataFrame(data,columns=['zx','gts','zf','yhl'],index=['age','year','mon_day'])
##获取(查看)某一列的数据--两种方法是一样的,下面两种方法一样
frame['gts']==frame.gts
get_col=frame.gts
##查看某一行的数据:
view_row=frame.ix['b']##用索引字段
#查看age year 行的 gts zf yhl列中的内容,没有为空(标签索引)
view_vol=frame.ix[['age','year'],['gts','zf','yhl']]
frame.reindex(index=['age','year'],col=['gts','zf','yhl'])#同样的效果
##更改行名、列名
frame2.rename_axis({'zx':'zhangxue','gts':'gaotianshu'},axis=1)##给出原列名和新列名的映射
frame2.rename_axis({'age':'nianling','year':'nian'})##给出原行名和新行名的映射
##修改某列的值数据--通过赋值(标量、数组)的方法
frame2.yhl=[51,1986,219]##若该列的值全相同,则只需给一个标量就好,不同就给定一组值(若是列表或者数组要保证长度必须和dataframe的长度相同)
##修改某列的值数据--通过赋值Series对象的方法:则必须精确给出要添加的值所对应的索引,以匹配DataFrame中的索引,没有给出值的索引空位都被填上nan
frame2.yk=Series([18,2002,314],index=['age','year','mon_day'])#给出全部索引和对应的值
#frame2.zyd=Series([50,923],index=['age','mon_day'])#该方法添加不成功
frame2['zyd']=Series([50,923],index=['age','mon_day'])#给出部分值和对应的索引,没有值的会被填为nan 该方法添加成功
frame2['pwf']=Series([123],index=['mon_day'])
##添加一个新列并赋值
frame2['alive']=frame2.zx==24##这样写居然也可以
##删除某列--del(原地)
del frame2['alive']
##返回丢弃掉给定行、列后(注意写法)的对象-非原地
frame.drop(['year','age'],)
frame.drop(['zx','yk'],axis=1)
obj5=Series(np.arange(5.),index=['zx','gts','zf','yk','dd'])
##删除某行(不是原地)
new_obj5=obj5.drop(['zf','zx'])##丢弃该两索引对应的值行返回新对象 不是在原地修改
##series 是一个有序的字典,因此索引即可是关键字,也可是下标序号:obj3[2]==obj3['zf']
##利用标签名的切片末端是包含的 ,这与普通的下标切片运算不同obj1['o':'u']!=obj1[0:2]
##DataFrame的索引frame2.ix就够了
##索引出zx 列的值大于100的所有行,这些行中取前两列(用看图划片的方式比较直观)
frame2.ix[frame2.zx>100,:2]##前面表示行,后面表示列,
frame2.ix[:,'zx']##查看zx列
##在算数方法中填充值
d1=DataFrame(np.arange(12.).reshape(3,4),columns=list('asdf'))
d2=DataFrame(np.arange(24.).reshape(4,6),columns=list('asgdfe'))
d1.add(d2,fill_value=0)##返回d1加d2的和,值为nan的空用d2对应的空补齐
#==============================================================================
##排序:
##series
obj2.sort_index()## series dui 索引
obj2.order()##对值排序-任何为nan都为末尾
##DataFrame
d2.sort_index()##dataframe 对行
d2.sort_index(axis=1,ascending=False)##dataframe 对列逆序
##根据多列进行排序,先根据a,若a相同,za在根部B
d3=DataFrame({'b':[4,7,-3,2],'a':[0,1,0,1]})
d3.sort_index(by=['a','b'])
path_name='/media/zzpp220/Data/Linux_Documents/DOWNLOAD/python-DataAnalysis/pydata-book-master/ch02/names/'
columns=['name','gender','births']
names1880=pd.read_csv(path_name+'yob1880.txt',names=['name','gender','births'])
names1880=names1880[:1000]
##补充查看列(行)的方法:
names1880.icol(range(1))#第0列
names1880.irow([1,3,5])##查看第1.3.5行
###统计汇总
col_sum=d3.sum()##按列对行求和,返回包含列小计的series
ind_sum=d3.sum(axis=1)#按行对列求和,返回包含行小计的series axis=0表示行,1表示列
names1880.births.mean()
names1880.births.describe()##返回一个一次性产生多个汇总统计的series
names1880.gender.describe()#f非数值型也返回汇总统计
#
#==============================================================================
# all_Data={}
# for tick in ['AAPL','IBM','MSFT','GOOG']:
# all_Data[tick]=web.get_data_yahoo(tick,'1/1/2000','1/1/2010')
# price=DataFrame({tic:data['Adj Close'] for tic,data in all_Data.iteritems()})
# volu=DataFrame({tic:data['Volume'] for tic,data in all_Data.iteritems()})
#
# returns=price.pct_change()
# returns.tail()##后10条
# ##两列的方差、协方差
# returns.GOOG.corr(returns.AAPL)
# returns.GOOG.cov(returns.AAPL)
# ## whe whole
# returns.corr()
# returns.cov()
#==============================================================================
##某个列()series对象的唯一值
unique=names1880.gender.unique()
vcount=names1880.gender.value_counts()## 返回一个series,计算一个series中各值出现的频率,按照频率的降序排列
pd.value_counts(vcount.values,sort=False)##左边是值,右边是出现次数
#ex1=pd.read_csv('/media/zzpp220/Data/Linux_Documents/DOWNLOAD/python-DataAnalysis/pydata-book-master/ch06/ex3.txt',names=['Date','a'])
#========滤出缺失数据============================================================
data=Series([2,3,NaN,6,7,NaN,8,3,NaN,5,7])
data.dropna()
frame2.dropna()###DataFrame默认丢弃任何含有缺失值的行
frame2.dropna(how='all')##仅丢弃全部是nan 的行
##滤除列缺失数据
frame2.dropna(axis=1)
frame2.dropna(axis=1,how='all')
##补全缺失值
frame2.fillna(0)#全部缺失值都用0补全
frame2.fillna({'zyd':21,'pwf':33})#指定列的缺失值用指定值补全,本行及上一行方法都是返回新对象
frame2.fillna({'zyd':21,'pwf':33},inplace=True)#原地补全
#========层次化索引 MultiIndex=============================================
##在数据重塑和分组操作中很重要
hierar=Series(np.random.randn(10),index=[list('aaabbbccdd'),[1,2,3,1,2,3,1,2,2,3]])
hierar['a']#查看父层索引a 下的全部数据
hierar[:,2]#前面表示父层,后面表示子层索引,选取子层索引为2的全部数据
hierar.unstack()##将具有多次索引的Series 安排到新的Dataframe中
##DataFrame 每条轴都可以有分层索引,他们叫做轴标签( a,s,zx,zf,year等)
thr_frame=DataFrame(np.arange(12).reshape(4,3),index=[list('aass'),[1,2,1,2]],columns=[['zx','zx','zf'],['year','mon_day','year']])
thr_frame.index.names=['par','kid']#设置行的索引名
thr_frame.columns.names=['name','info']#设置列的索引名
'''
thr_frame
Out[94]:
name zx zf
info year mon_day year
par kid
a 1 0 1 2
2 3 4 5
s 1 6 7 8
2 9 10 11
'''
thr_frame['zx']##选取父列
thr_frame[('zx','year')]#查看子列
thr_frame.ix['a',('zx','year')]#查看上面子列记录中横轴标签是a的行
thr_frame.ix[('a',2),('zx','year')]#查看上面子列记录中横轴父、子标签分别是a,2的行
###========重排分级顺序--层次化索引 MultiIndex=============================================
'''有时候需要根据级别上的值对数据进行排序,用swaplevel,接受两个级别编号或者名称,并返回一个互换了级别的新对象'''
thr_frame.swaplevel('name','info',axis=1)##纵轴 父子标签呼唤
thr_frame.swaplevel(0,1,axis=1)##同上 纵轴只有两层标签,互换
'''用了swaplevel之后,父轴的标签都展开了,不是说像叠起来一样'''
thr_frame.swaplevel('par','kid')##横轴 父子标签互换
thr_frame.swaplevel(0,1)#同上
thr_frame.swaplevel(0,1).sortlevel(0)#根据交换后的父层大小进行怕徐,这个时候都父层叠起来了
'''
thr_frame.swaplevel(0,1)
Out[92]:
name zx zf
info year mon_day year
kid par
1 a 0 1 2
2 a 3 4 5
1 s 6 7 8
2 s 9 10 11
thr_frame.swaplevel(0,1).sortlevel(0)
Out[93]:
name zx zf
info year mon_day year
kid par
1 a 0 1 2
s 6 7 8
2 a 3 4 5
s 9 10 11
'''
###========根据级别汇总统计--层次化索引 MultiIndex=======''''''
thr_frame.sum(level='kid')#thr_frame.sum(level=1) 二者相同 统计行的级别
thr_frame.sum(axis=1,level=1)#统计列的级别
'''
thr_frame.sum(level=1)
Out[4]:
name zx zf
info year mon_day year
kid
1 6 8 10
2 12 14 16
thr_frame.sum(axis=1,level=1)
Out[5]:
info mon_day year
par kid
a 1 1 2
2 4 8
s 1 7 14
2 10 20
'''
'''合并(merge)-列或者连接(concat)-行数据集'''
mer=pd.merge(frame,fram2,on=['zx','gts','zf'])## 默认的是内连接 显示交集,显式指定用这三个列进行列连接