DataFrame基础用法2

数据分析用到的

1. apply 直接传函数

def add_prop(group):
    births=group.births.astype(float)
    group['prop']=births/births.sum()
    return group
names=names.groupby(['year','sex']).apply(add_prop)
 

2.用np.allcolse()来检查分组总计值是否接近1

print np.allclose(names.groupby(['year','sex']).prop.sum(),1)
返回:true
3.取该数据集的子集:每对sex/year组合的前1000名
def get_top1000(group):
    return group.sort_index(by='births',ascending=False)[:1000]
grouped=names.groupby(['year','sex'])
top1000=grouped.apply(get_top1000)
print top1000
4.生成一张year,name统计表,查看下面4个名字取名的趋势,画张列表

.取该数据集的子集:每对sex/year组合的前1000名

total_births=top1000.pivot_table('births',index='year',columns='name',aggfunc=sum)
# print total_births
subset=total_births[['John','Harry','Mary','Marilyn']]
subset.plot(subplots=True,figsize=(12,10),grid=False,title="Number of births per year")
pl.show()
 
验证父母给小孩起常见的名字越来越少:办法是计算最流行的1000个名字所占的比例
table=top1000.pivot_table('prop',index='year',columns='sex',aggfunc=sum)
table.plot(title='sum of table1000.prop by year and sex',yticks=np.linspace(0,1.2,13),xticks=range(1880,2020,10))
pl.show()
 
 
5.unique与drop_duplicates区别
#dataframe中去重函数,drop_duplicates是返回一个移除了重复行的DataFrame
data=pd.DataFrame({'K':[1,1,2,2,3,4,2]})
print data
IsDuplicated=data.duplicated()
print IsDuplicated
print type(IsDuplicated)
data=data.drop_duplicates()
print data
#ISDuplicated和drop_duplicates是判断全部列,也可以指定部分列进行重复项判断
# data.drop_duplicates(['k2']) #对名字为k2的列进行去重

取不重复的值

all_names=top1000.name.unique() #取不重名的名字

6. index 与reindex的区别  

用index修改的索引不存在会报错,而reindex则会用None填充
obj=pd.Series(range(4),index=['d','b','a','c') 
#返回结果如下
d    0
b    1
a    2
c    3
obj=pd.Series(range(4),index=['d','b','a','c','e']) #会报错,因为‘e’超出了范围,不存在此索引
print obj
#但用reindex则会用None填充
#reindex更多的不是修改pandas对象的索引,而只是修改索引的顺序,如果修改的索引不存在就会使用默认的None代替此行。
# 且不会修改原数组,要修改需要使用赋值语句。
print obj.reindex(['a', 'b', 'c', 'd', 'e'])
#返回结果如下:
a    2.0
b    1.0
c    3.0
d    0.0
e    NaN

7.索引对象:Index

pandas的索引对象负责管理轴标签和其它元数据(比如轴名称等),构建Series或DataFrame时,
所用到的任何数组或其它序列的标签都会被转换成一个Index:
obj=Series(range(3),index=['a','b','c'])
index=obj.index
print obj
#输出结果如下:
# a    0
# b    1
# c    2
print index  #输出结果:Index([u'a', u'b', u'c'], dtype='object')
print index[1:]  #输出结果:Index([u'b', u'c'], dtype='object')
(1)Index对象是不可修改的(immutable),因此用户不能对其进行修改
# index[1]='d'
# print index  #报错: Index does not support mutable operations
#注意:不可修改性非常重要,因为这样才能使Index对象在多个数据结构之间安全共享:
index=pd.Index(np.arange(3))
obj2=Series([1.5,-2.5,0],index=index)
print obj2
#输出结果如下:
# 0    1.5
# 1   -2.5
# 2    0.0
# dtype: float64
print obj2.index is index  #输出结果:True
print "1" in obj2.index    #"1"是obj2的行索引吗?#输出结果是False
# print "1" in obj2.columns  #报错,Series没有列索引,不象datafram表格类型
print '0' in obj2.index

pandas中主要的Index对象

Index   		最泛化的Index对象,将轴标签表示为一个由python对象组成的Numpy数组
Int64Index	    针对整数的特殊Index
MultiIndex		“层次化”索引对象,表示单个轴上的多层索引。可以看做由元组组成的数组
DatetimeIndex	 存储纳秒组时间戳
PeriodIndex		 针对Period数据(时间间隔)的特殊Index

7.重新索引:reindex

pandas对象的一个重要方法是reindex,其作用是创建一个适应新索引的新对象
obj1=Series([4.5,7.2,-5.3,3.6],index=['d','b','a','c'])
print obj1
#输出结果如下:
# d    4.5
# b    7.2
# a   -5.3
# c    3.6
# dtype: float64
#调用该Series的reindex将会根据新索引进行重排。如果某个索引值当前不存在,就引入缺失值
obj2=obj1.reindex(['a','b','c','d','e'])
print obj2
#输出结果如下:
# a   -5.3
# b    7.2
# c    3.6
# d    4.5
# e    NaN
# dtype: float64
obj2=obj1.reindex(['a','b','c','d','e'],fill_value=0)
print obj2
#输出的结果如下:
# a   -5.3
# b    7.2
# c    3.6
# d    4.5
# e    0.0
# dtype: float64

对于时间序列这样的有序数据,重新索引时可能需要做一些插值处理。method选项即可达到此目的,例如,使用ffill可以实现前向值填充

obj3=Series(['blue','purple','yellow'],index=[0,2,4])
obj3.reindex(range(6),method='ffill')
print obj3
#输出的结果:
# 0   blue
# 1   blue
# 2   purple
# 3   purple
# 4   yellow
# 5   yellow
列出了可用的method选项。其实我们有时需要比前向和后向填充更为精准的插值方式

reindex的插值method选项
参数 说明
ffill或pad 前向填充值

bfill或backfill 后向填充值

对于DataFrame,reindex可以修改(行)索引、列,或两个都修改。如果仅传入一个序列,则会重新索引行

frame=DataFrame(np.arange(9).reshape((3,3)),index=['a','c','d'],
                columns=['Ohio','Texas','California'])
print frame
#输出结果如下:
#    Ohio  Texas  California
# a     0      1           2
# c     3      4           5
# d     6      7           8
frame2=frame.reindex(['a','b','c','d'])
print frame2
#输出结果如下:
#    Ohio  Texas  California
# a   0.0    1.0         2.0
# b   NaN    NaN         NaN
# c   3.0    4.0         5.0
# d   6.0    7.0         8.0
#使用columns关键字即可重新索引列:
states=['Texas','Utah','California']
frame2=frame.reindex(columns=states)
print frame2
#输出结果如下:
#    Texas  Utah  California
# a      1   NaN           2
# c      4   NaN           5
# d      7   NaN           8
利用ix的标签索引功能,重新索引任务可以变得更简洁
print frame2.ix[['a','b','c','d'],states]

reindex函数的参数

index		用作索引的新序列,即可以是Index实例,也可以是其它序列型的python数据结构
method		插值(填充)方式
fill_value	在重新索引的过程中,需要引入缺失值时使用的替代值
limit		前向或后向填充时的最大填充量
level		在MultiIndex的指定级别上匹配简单索引,否则选取其子集
copy		默认为True,无认如何都复制;如果为False,则新旧相等就不复制

8.丢弃指定轴上的项:drop

丢弃某条轴上的一个或多个项很简单,只要有一个索引数组或列表即列。

drop方法返回的是一个在指定轴上删除了指定值的新对象。

import numpy as np
from pandas import Series,DataFrame
import pandas as pd

obj=Series(np.arange(5.),index=['a','b','c','d','e'])
new_obj=obj.drop('c')
print new_obj
#输出结果如下:
# a    0.0
# b    1.0
# d    3.0
# e    4.0
# dtype: float64
new_obj=obj.drop(['d','c'])
print new_obj
#输出结果如下 :
# a    0.0
# b    1.0
# e    4.0
# dtype: float64
对于DataFrame,可以删除任意轴上的索引值:
data=DataFrame(np.arange(16).reshape((4,4)),
               index=['Ohio','Colorado','Utah','New York'],
               columns=['one','two','three','four'])
print data
#输出结果如下:
#           one  two  three  four
# Ohio        0    1      2     3
# Colorado    4    5      6     7
# Utah        8    9     10    11
# New York   12   13     14    15
new_data=data.drop(['Colorado','Ohio'])
print new_data
#输出结果如下:
#           one  two  three  four
# Utah        8    9     10    11
# New York   12   13     14    15
new_data=data.drop('two',axis=1)
print new_data
#输出结果如下:
#           one  three  four
# Ohio        0      2     3
# Colorado    4      6     7
# Utah        8     10    11
# New York   12     14    15
# new_data=data.drop('two',axis=0) #axis=0是指行,axis=1指一整列
# print new_data  #报错:labels ['two'] not contained in axis,two没有包启在axis=0的行索引中,它是列的索引,故只能用axis=1
new_data=data.drop(['two','four'],axis=1) #axis=1列中索引为'two','four'
print new_data
#输出结果如下:
#           one  three
# Ohio        0      2
# Colorado    4      6
# Utah        8     10
# New York   12     14

9.索引、选取和过滤

Series的选取、过滤介绍:

Series索引(obj[...])的工作方式类似于Numpy数组的索引,只不过Series的索引值不只是整数.

(1)它可以像数组一样以下标形式取出,也可以用行索引,ix是用于DataFrame中的行索引。
obj['b'],obj[1]
(2)可以切片取值,下标的切片与python一样,右边是不包含的:obj[2:4] 
(3)取出多个行:用索引值取或者用下标取,但都用[[]](即双括号)
obj[['b','a','d']]
obj[[1,3]]
(4)可用条件,布尔型
obj[obj<2]

(5)但用标签(即行索引)的切片运算,它与python不一样,是包含右边的

import numpy as np
from pandas import Series,DataFrame
import pandas as pd

# Series索引、选取和过滤
obj=Series(np.arange(4),index=['a','b','c','d'])
print obj
#输出结果如下:
# a    0
# b    1
# c    2
# d    3
# dtype: int64
print obj['b']  #与下面的下标取值是一样的obj[1],下标是从0开始算的
#输出结果: 1
print obj[1]
#输出结果: 1
print obj[2:4]  #取出从下标为2-4的但不包含右边的值4,即取出下标为2,3的值
#输出结果如下:
# c    2
# d    3
print obj[['b','a','d']] #取多行,按行索引取出多行
#输出结果如下:
# b    1
# a    0
# d    3
# dtype: int64
print obj[[1,3]]  #取多行,取出下标为1,3行的,下标从0开始
#输出结果如下:
# b    1
# d    3
# dtype: int64
print obj[obj<2] #obj<2的值为True,即0,1,再取出obj[True]为true的值
#输出结果如下:
# a    0
# b    1
# dtype: int64
print obj['b':'c']  #标签(即行索引,Series没有列索引)切片,包含右边值
# b    1
# c    2
# dtype: int64
#切片的值设置很简单,直接赋值即可
obj['b':'c']=5
print obj
#输出结果如下:
# a    0
# b    5
# c    5
# d    3
# dtype: int64

DataFrame的选取、过滤介绍:

DataFrame进行索引其实就比Series多获取一个或多个列
行可以用切片,列不可以用切片
(1) 获取单列(和Series一样):用列索引获取
data['two']
DataFrame就不能像Series用单个下标了,因为它是表格形式(有行,列下标,单个它没法分清),而Series是数组.
data[2,3] data[2]都会报错
(2) 获取多列:用[[]]
data[['three','one']]
(3) 切片选取行(与Series一样,下标方式获取):
data[:2]
(4) 布尔型数组选取行,与ndarray一样
data[data['three']>5]    data[data<5]=0    data.ix[data.three>5,:3]
(5) 标签进行行索引,引入了字段ix.px 它可以通过Numpy式的标记法以及轴标签从DataFrame中选取行和列的子集。
即先取出行,再取列的子集
data.ix['Colorado',['two','three']]
(6) 用标签ix索引取多行多列:先取多行用ix,再取多列子集(列可用下标,下标从0开始算)
data.ix[['Colorado','Utah'],[3,0,1]]
data.ix[['Colorado','Utah'],['two','three']]
(7) 取整行:ix[下标],ix['行索引']

data.ix[2]    data.ix[:'Utah','two']

import numpy as np
from pandas import Series,DataFrame
import pandas as pd

data=DataFrame(np.arange(16).reshape((4,4)),
               index=['Ohio','Colorado','Utah','New York'],
               columns=['one','two','three','four'])
print data
#输出结果如下:
#           one  two  three  four
# Ohio        0    1      2     3
# Colorado    4    5      6     7
# Utah        8    9     10    11
# New York   12   13     14    15
print "++++++++++++++++++++++++++"
print data['two']  #取出列索引为'two'的值
#输出结果如下:
# Ohio         1
# Colorado     5
# Utah         9
# New York    13
# Name: two, dtype: int64
print "+++++++++++++++++++++++++"
print data[['three','one']]
#输出结果如下:
#           three  one
# Ohio          2    0
# Colorado      6    4
# Utah         10    8
# New York     14   12
print data[:2] #下标从0开始,右边不包含。故取出的是下标为0,1的行
#输出结果如下:
#           one  two  three  four
# Ohio        0    1      2     3
# Colorado    4    5      6     7
print data[data['three']>5]  #data['three']>5返回布尔值,若是>5的则返回True,再data['True']取出为true的值
#输出结果如下:
#           one  two  three  four
# Colorado    4    5      6     7
# Utah        8    9     10    11
# New York   12   13     14    15
data[data<5]=0 #将data<5的值赋0
print data
#输出结果如下:
#           one  two  three  four
# Ohio        0    0      0     0
# Colorado    0    5      6     7
# Utah        8    9     10    11
# New York   12   13     14    15
利用ix取行索引,还可取出行索引和列的子集
print data.ix['Colorado',['two','three']]  #ix标签行索引为'colorado'的,再取子集的列索引为['two','three']的值
#输出结果如下:
# two      5
# three    6
# Name: Colorado, dtype: int64
print data.ix[['Colorado','Utah'],[3,0,1]]  #多行多列,用ix先取多行,再用下标取多列子集
#输出结果如下:
#           four  one  two
# Colorado     7    0    5
# Utah        11    8    9
print data.ix[['Colorado','Utah'],['two','three']]
#输出结果如下:
#           two  three
# Colorado    5      6
# Utah        9     10
print data.ix[2]   #取出的是# Utah  8  9  10 11这行的数据,下标从0开始算
#输出结果如下:
# one       8
# two       9
# three    10
# four     11
# Name: Utah, dtype: int64
print data.ix[:'Utah','two'] #行用切片(标签切片包含最右边的),列子集只有一个用列索引
#输出结果如下:
# Ohio        0
# Colorado    5
# Utah        9
# Name: two, dtype: int64
print data.ix[data.three>5,:3]  #data.three列的值>5的行为True,再取出列为:3,
# 故取出的是前3列(下标切片3不包含,切片右边数据不包含)
#输出结果如下:
#           one  two  three
# Colorado    0    5      6
# Utah        8    9     10
# New York   12   13     14

DataFrame的索引选项

类型						说明
obj[val]                   选取DataFrame的单个列或一组列。在一些特殊情况下会比较便利:布尔型数组(过滤片)、
				   切片(行切片)、布尔型DataFrame(根据条件设置值)
obj.ix[val]                选取DataFrame的单个行或一组行
obj.ix[:,val]              选取单个列或列子集
obj.ix[val1,val2]          同时选取行和列
reindex方法		   将一个或多个轴匹配到新索引
xs方法			   根据标签选取单行或单列,并返回一个Series
icol,irow方法	           根据整数位置选取单列或单行,并返回一个Series
get_value、set_value方法    根据行标签和列标签选取单个值

10.算术运算和数据对齐

pandas最重要的功能是,它可以对不同索引的对象进行算术运算。
在将对象相加时,如果存在不同的索引对,则结果的索引就是该索引对的交集。

例如下面的s1+s2,就是s1,s2的索引对的并集,即索引在s1,s2中都有的,则s1+s2;若没有索引非重叠,则用Nan

(1)Series的算术运算和数据对齐:

s1=Series([7.3,-2.5,3.4,1.5],index=['a','c','d','e'])
s2=Series([-2.1,3.6,-1.5,4,3.1],index=['a','c','e','f','g'])
print s1
print s2
#输出结果如下:
# a    7.3
# c   -2.5
# d    3.4
# e    1.5
# dtype: float64
#
# a   -2.1
# c    3.6
# e   -1.5
# f    4.0
# g    3.1
# dtype: float64
print s1+s2  #s1,s2的索引对的并集,即索引在s1,s2中都有的,则s1+s2
#输出的结果如下:
# a    5.2
# c    1.1
# d    NaN
# e    0.0
# f    NaN
# g    NaN
# dtype: float64

(2)对于DataFrame,对齐操作同时发生在行和列上:

df1=DataFrame(np.arange(9).reshape((3,3)),columns=list('bcd'),
              index=['Ohio','Texas','Colorado'])
df2=DataFrame(np.arange(12).reshape((4,3)),columns=list('bde'),
              index=['Utah','Ohio','Texas','Oregon'])
print df1
print df2
#输出结果如下:
#           b  c  d
# Ohio      0  1  2
# Texas     3  4  5
# Colorado  6  7  8
#
#         b   d   e
# Utah    0   1   2
# Ohio    3   4   5
# Texas   6   7   8
# Oregon  9  10  11
#把它们相加后将会返回一个新的DataFrame,其索引和列为原来那两个DataFrame的并集
print df1+df2
#输出结果如下:
#             b   c     d   e
# Colorado  NaN NaN   NaN NaN     #Colorado在df2中无此行索引,故全为NaN
# Ohio      3.0 NaN   6.0 NaN      #ohio索引df1,df2中都有,列共同有的只有b,d,故其它列都是NaN
# Oregon    NaN NaN   NaN NaN
# Texas     9.0 NaN  12.0 NaN
# Utah      NaN NaN   NaN NaN

11.在算术方法中填充值

在算术中若像上面存在NaN的值(缺省值),可以用特定值来填充。在对不同索引的对象进行算术运算时,你可能希望当一个对象

中某个轴标签在另一个对象中找不到时填充一个特殊值(比如0):

import numpy as np
from pandas import Series,DataFrame
import pandas as pd

df1=DataFrame(np.arange(12).reshape((3,4)),columns=list('abcd'))
df2=DataFrame(np.arange(20).reshape((4,5)),columns=list('abcde'))
print df1
print df2
#输出结果如下:
#    a  b   c   d
# 0  0  1   2   3
# 1  4  5   6   7
# 2  8  9  10  11
#
#     a   b   c   d   e
# 0   0   1   2   3   4
# 1   5   6   7   8   9
# 2  10  11  12  13  14
# 3  15  16  17  18  19
print df1+df2  #将它样相加,没有重叠的位置就会产生Na值
#输出结果如下:
#       a     b     c     d   e
# 0   0.0   2.0   4.0   6.0 NaN
# 1   9.0  11.0  13.0  15.0 NaN
# 2  18.0  20.0  22.0  24.0 NaN
# 3   NaN   NaN   NaN   NaN NaN
(1)方法1:使用df1的add方法(将+改成方法add,可传入填充的参数值),传入df2以及一个fill_value参数:
print df1.add(df2,fill_value=0)
#输出结果如下:
#       a     b     c     d     e
# 0   0.0   2.0   4.0   6.0   4.0
# 1   9.0  11.0  13.0  15.0   9.0
# 2  18.0  20.0  22.0  24.0  14.0
# 3  15.0  16.0  17.0  18.0  19.0
(2)方法2:与上面类似,在对Series或DataFrame重新索引时,也可以指定一个填充值:
print df1.reindex(columns=df2.columns,fill_value=0)  #df1重新修改列索引,列索引的值=df2.columns,若与df2.columns不相同则填充0
#输出结果如下:
#    a  b   c   d  e
# 0  0  1   2   3  0
# 1  4  5   6   7  0
# 2  8  9  10  11  0
#注意:add和reindex方法的不同之处:
# df1.add(df2,fill_value=0) add方法是以df2为主的,行和列若只在df2中有,在df1中没有。则留原来df2的原值
# df1.reindex(columns=df2.columns,fill_value=0) reindex方法是修改df1中的例,其列索引=df2.columns,故列df1的e列没有,
# 修改后的列名中有e列,但它的值是0.(即列的并集)。但是行没有在参数中,故行是以df1为主,df1只有0,1,2三行。
注意:add和reindex方法的不同之处:
df1.add(df2,fill_value=0) add方法是df1,df2都有,但不重叠,则会保留df1,df2的原值,若两者都没有值,则返回NaN.
df1.reindex(columns=df2.columns,fill_value=0) reindex方法是修改df1中的例,其df1列索引=df2.columns,故列df1的e列没有,
修改后的列名中有e列,但它的值是0.(即列的并集)。但是行没有在参数中,故行是以df1为主,df1只有0,1,2三行。
再举一个df1,df2都有不同列的例子如下:
import numpy as np
from pandas import Series,DataFrame
import pandas as pd

df1=DataFrame(np.arange(12).reshape((3,4)),columns=list('abfd'))
df2=DataFrame(np.arange(20).reshape((4,5)),columns=list('abcde'))
print df1
print df2
#输出结果如下:
#    a  b   f   d
# 0  0  1   2   3
# 1  4  5   6   7
# 2  8  9  10  11
#     a   b   c   d   e
# 0   0   1   2   3   4
# 1   5   6   7   8   9
# 2  10  11  12  13  14
# 3  15  16  17  18  19

print df1+df2  #将它样相加,没有重叠的位置就会产生Na值
#输出结果如下:
#       a     b   c     d   e   f
# 0   0.0   2.0 NaN   6.0 NaN NaN
# 1   9.0  11.0 NaN  15.0 NaN NaN
# 2  18.0  20.0 NaN  24.0 NaN NaN
# 3   NaN   NaN NaN   NaN NaN NaN
print df1.add(df2,fill_value=0)
#输出结果如下:
#       a     b     c     d     e     f
# 0   0.0   2.0   2.0   6.0   4.0   2.0
# 1   9.0  11.0   7.0  15.0   9.0   6.0
# 2  18.0  20.0  12.0  24.0  14.0  10.0
# 3  15.0  16.0  17.0  18.0  19.0   NaN
print df1.reindex(columns=df2.columns,fill_value=0)  #df1重新修改列索引,列索引的值=df2.columns,若与df2.columns不相同则填充0
#输出结果如下:
#    a  b  c   d  e
# 0  0  1  0   3  0
# 1  4  5  0   7  0
# 2  8  9  0  11  0
灵活的算术方法:
方法         说明
add 用于加法(+)的方法
sub 用于减法(-)的方法
div 用于除法(/)的方法
mul 用于乘法(*)的方法

12.DataFrame和Series之间的运算

跟Numpy数组一样,DataFrame和Series之间算术运算也是有明确规定的。

import numpy as np
from pandas import Series,DataFrame
import pandas as pd

#下面是array数组的相减,计算一个二维数组与某行之间的差
arr=np.arange(12.).reshape((3,4))
print arr
#输出结果如下:
# [[  0.   1.   2.   3.]
#  [  4.   5.   6.   7.]
#  [  8.   9.  10.  11.]]
print arr[0]
#输出结果:[ 0.  1.  2.  3.]
print arr-arr[0]
#输出结果如下:
# [[ 0.  0.  0.  0.]
#  [ 4.  4.  4.  4.]
#  [ 8.  8.  8.  8.]]
这就叫广播

DataFrame和Series之间的运算差不多也是如此:

import numpy as np
from pandas import Series,DataFrame
import pandas as pd


frame=DataFrame(np.arange(12.).reshape((4,3)),columns=list('bde'),
                index=['Utah','Ohio','Texas','Oregon'])
print frame
#输出结果如下:
#           b     d     e
# Utah    0.0   1.0   2.0
# Ohio    3.0   4.0   5.0
# Texas   6.0   7.0   8.0
# Oregon  9.0  10.0  11.0
series=frame.ix[0]  #ix是取dataframe的行下标为0的一行数据,即第一行数据
print series
#输出结果如下:
# b    0.0
# d    1.0
# e    2.0
# Name: Utah, dtype: float64
print frame-series
#输出结果如下:
#           b    d    e
# Utah    0.0  0.0  0.0
# Ohio    3.0  3.0  3.0
# Texas   6.0  6.0  6.0
# Oregon  9.0  9.0  9.0
如果某个索引值在DataFrame的列或Series的索引中找不到,则参与运算的两个对象就会被重新索引以形成并集
series2=Series(range(3),index=['b','e','f'])
print series2
#输出结果如下:
# b    0
# e    1
# f    2
# dtype: int64
print frame+series2   #列只有b,e有,d,f没有,则并集计算
#输出的结果如下:
#           b   d     e   f
# Utah    0.0 NaN   3.0 NaN
# Ohio    3.0 NaN   6.0 NaN
# Texas   6.0 NaN   9.0 NaN
# Oregon  9.0 NaN  12.0 NaN
若你希望匹配行且在列上广播,则必须使用算术运算方法。
series3=frame['d']  #series3取的是frame['d']上的一列数据,因为series是数组只有行索引。它不是DataFrame表格形式
print frame
print series3
#输出结果如下:
# Utah       1.0
# Ohio       4.0
# Texas      7.0
# Oregon    10.0
# Name: d, dtype: float64
print frame.sub(series3,axis=0)
#输出的结果如下:frame['d']列-series3得到该列的结果是0
#           b    d    e
# Utah   -1.0  0.0  1.0
# Ohio   -1.0  0.0  1.0
# Texas  -1.0  0.0  1.0
# Oregon -1.0  0.0  1.0

13.函数应用和映射

Numpy的ufuncs(元素级数组方法)也可用于操作Pandas对象,
若要每次生成的随机数一样则用seed,np.random.randn(4,3),np.seed(0),see()里的参数一致随机生成的就一致。
import numpy as np
from pandas import Series,DataFrame
import pandas as pd
下面举例中用的是randn,没有用seed,故每次运行的随机frame的值都不一样。下面的输出结果是不一样的。

frame=DataFrame(np.random.randn(4,3),columns=list('bde'),
                index=['Utah','Ohio','Texas','Oregon'])

print frame
#输出结果如下:
#                b         d         e
# Utah    0.717460 -0.686366  0.678220
# Ohio    0.821139 -0.266131  0.780161
# Texas  -0.956684 -1.301178  1.863898
# Oregon -1.106230  1.590944 -0.366192
print np.abs(frame)
#输出结果如下:
#                b         d         e
# Utah    0.717460  0.686366  0.678220
# Ohio    0.821139  0.266131  0.780161
# Texas   0.956684  1.301178  1.863898
# Oregon  1.106230  1.590944  0.366192
另一种常见的操作是,将函数应用到由各列或行所形成的一维数组上。DataFrame的apply方法即可实现
f=lambda x:x.max()-x.min()
print frame.apply(f)  #没有参数,默认axis=0即列,每一列的值用最大值-最小值,得到b,d,e列的值
# b    2.613551
# d    1.960512
# e    2.738963
# dtype: float64
print frame.apply(f,axis=1)  #axis=1是每一行上最大值-最小值得到到下面的行
#输出结果如下:因为随机数每次产生的结果都不一样。故算的结果也不一样。
# Utah      0.415836
# Ohio      2.827663
# Texas     0.339280
# Oregon    2.702060
# dtype: float64
#许多最为常见的数组统计功能都实现成DataFrame的方法(如sum和mean),因此无需使用apply方法
除标量值外(即单行值),传递给apply的函数还可以返回由多个值组成的Series:
def f(x):
    return Series([x.min(),x.max()],index=['min','max'])
print frame.apply(f)
#输出结果如下:
#             b         d         e
# min -2.036368 -1.635511 -0.817457
# max  0.641699  0.997854  0.303625
此外,元素级的Python函数也是可以用的。假如你想得到frame中各个浮点值的格式化字符吕,使用applymap即可
format=lambda x:'%.2f'%x
print frame.applymap(format)
#输出结果如下:
#             b      d      e
# Utah     2.01  -2.30   0.27
# Ohio    -0.61   0.77   0.74
# Texas    0.74   1.50  -0.51
# Oregon   1.78  -0.01   0.33
#之所以叫做applymap,是因为Series有一个用于应用元素级函数的map方法
print frame['e'].map(format)  #单独取出DataFrame的一列就是Series了,然后用Series方法即可
#输出结果如下
# Utah      -1.65
# Ohio       0.80
# Texas      1.12
# Oregon    -0.14
# Name: e, dtype: object
14.排序和排名
a.按索引排序
根据条件对数据集排序sorting;要对行或列索引进行排序(按字典排序),可使用sort_index方法,
它将返回一个已排序的新对象。
注意:Series用range,DataFrame用arange

(1) Series排序

obj=Series(range(4),index=['d','a','b','c'])
print obj
#输出结果:
# d    0
# a    1
# b    2
# c    3
print obj.sort_index()  #sort_index,Series按行索引排序,Series只有行
#输出的结果如下:
# a    1
# b    2
# c    3
# d    0
# dtype: int64
(2)对于DataFrame,则可以根据任意一个軕上的索引进行排序
frame=DataFrame(np.arange(8).reshape((2,4)),
                index=['three','one'],
                columns=['d','a','b','c'])
print frame
#输出结果如下:
#        d  a  b  c
# three  0  1  2  3
# one    4  5  6  7
print frame.sort_index()   #没有axis参数,表示默认axis=0,即行索引排序
#输出结果如下:
#        d  a  b  c
# one    4  5  6  7
# three  0  1  2  3
print frame.sort_index(axis=1)  #axis=1,表示列索引排序:a,b,c,d
#输出结果如下:
#        a  b  c  d
# three  1  2  3  0
# one    5  6  7  4
数据默认是按升序排列的,但也可以降序排序,参数ascending=False。即列为d,c,b,a
print frame.sort_index(axis=1,ascending=False)
#输出结果如下:
#        d  c  b  a
# three  0  3  2  1
# one    4  7  6  5
b.按值进行排序
(1)对Series进行排序
若要按值对Series进行排序,可使用其order方法:
obj=Series([4,7,-3,2])
print obj.sort_values()    #老版本用sort_value()
# print obj.order()    #pandas新版本用order()
#输出结果如下:对值排序
# 2   -3
# 3    2
# 0    4
# 1    7
# dtype: int64
在排序时,任何缺失值默认都会被放到Series的末尾:
obj=Series([4,np.nan,7,np.nan,-3,2])
# print obj.order()
print obj.sort_values()
#输出结果如下:
# 4   -3.0
# 5    2.0
# 0    4.0
# 2    7.0
# 1    NaN
# 3    NaN
# dtype: float64
(2)在DataFrame上,可以根据一个或多个列中的值进行排序。将一个或多个列的名字传递给by选项即可达到目的。
frame=DataFrame({'b':[4,7,-3,2],'a':[0,1,0,1]})
print frame
#输出结果如下:
#    a  b
# 0  0  4
# 1  1  7
# 2  0 -3
# 3  1  2
# print frame.sort_index(by='b')
#输出结果如下:
#    a  b
# 2  0 -3
# 3  1  2
# 0  0  4
# 1  1  7
要根据多个列进行排序,传入名称的列表即可:
print frame.sort_index(by=['a','b'])
#输出结果如下:
#    a  b
# 2  0 -3
# 0  0  4
# 3  1  2
# 1  1  7
ranking排名跟排序关系密切,且它会增设一个排名值(从1开始,一直到数组中有效数据的数量)。
它跟numpy.argsort产生的间接排序索引差不多,只不过它可以根据某种规则破坏平级关系。

默认情况下,rank是通过"为各组分配一个平均排名"的方式破坏平级关系的。
obj=Series([7,-5,7,4,2,0,4])
print obj.rank()
#输出结果如下:
# 0    6.5
# 1    1.0
# 2    6.5
# 3    4.5
# 4    3.0
# 5    2.0
# 6    4.5
# dtype: float64
#也可以根据值在原数据中出现的顺序给出排名
print obj.rank(method='first')
#输出结果如下:
# 0    6.0
# 1    1.0
# 2    7.0
# 3    4.0
# 4    3.0
# 5    2.0
# 6    5.0
# dtype: float64
#当然,你也可以按降序进行排名:
print obj.rank(ascending=False,method='max')
#输出结果如下:
# 0    2.0
# 1    7.0
# 2    2.0
# 3    4.0
# 4    5.0
# 5    6.0
# 6    4.0
# dtype: float64

#DataFrame可以在行或列上计算排名:
frame=DataFrame({'b':[4.3,7,-3,2],'a':[0,1,0,1],
                 'c':[-2,5,8,-2.5]})
print frame
#输出结果如下:
#    a    b    c
# 0  0  4.3 -2.0
# 1  1  7.0  5.0
# 2  0 -3.0  8.0
# 3  1  2.0 -2.5
print frame.rank(axis=1)
#输出结果如下:
#      a    b    c
# 0  2.0  3.0  1.0
# 1  1.0  3.0  2.0
# 2  2.0  1.0  3.0
# 3  2.0  3.0  1.0

排名时(rank)用于破坏平级关系的method选项
method 说明
‘average’ 默认:在相等分组中,为各个值分配平均排名
‘min’ 使用整个分组的最小排名
‘max’ 使用整个分组的最大排名
‘first’ 按值在原始数居中的出现顺序分配排名

15.带有重得值的轴索引

许多pandas函数(如reindex)都要求标签唯一,但这并不是强制性的。它也可以带有重复索引值的Series.

obj=Series(range(5),index=['a','a','b','b','c'])
print obj
#输出结果如下:
# a    0
# a    1
# b    2
# b    3
# c    4
# dtype: int64
索引的is_unique属性可以告诉你它的值是否是唯一的:
print obj.index.is_unique   #输出结果是:False
对于带有重复值的索引,数据选取的行为将会有些不同。如果某个索引对应多个值,则返回一个Series;
而对应单个值的,则返回一个标量值(即一行)
print obj['a']
#返回结果如下:
# a    0
# a    1
# dtype: int64
print obj['c'] #返回:4
DataFrame的行进行索引也是如此:
df=DataFrame(np.random.randn(4,3),index=['a','a','b','b'])
print df
#输出结果如下:
#           0         1         2
# a -0.008028 -0.066083 -1.412515
# a  1.291454  0.301502 -1.470759
# b -1.046987 -1.236650  0.367174
# b -0.913669  0.035940  0.327931
print df.ix['b']  #ix取行索引
#输出结果如下:
#           0        1         2
# b -1.046987 -1.23665  0.367174
# b -0.913669  0.03594  0.327931
16.汇总和计算描述统计
pandas对象拥有一组常用的数学和统计方法。它们在部分都属于约简和汇总统计,
用于对Series中提取单个值(如sum或mean)或从DataFrame的行或列中提取一个Series.

跟对应的Numpy数组方法相比,它们都是基于没有缺失数据的假设来构建的。
df=DataFrame([[1.4,np.nan],[7.1,-4.5],
              [np.nan,np.nan],[0.75,-1.3]],
             index=['a','b','c','d'],
             columns=['one','two'])
print df
#输出结果如下:
#     one  two
# a  1.40  NaN
# b  7.10 -4.5
# c   NaN  NaN
# d  0.75 -1.3
调用DataFrame的sum方法将会返回一个含有小计的Series:每一列求和
print df.sum()
#输出结果如下:
# one    9.25
# two   -5.80
若传入axis=1将会按进行求和运算:
#输出结果如下:
# a    1.40
# b    2.60
# c     NaN
# d   -0.55
Na值会自动被排除,除非整个切片(这里指的是行或列,即一整行或一整列)都是NA.通过skipna选项可以禁用该功能。
print df.mean(axis=1,skipna=False)
#输出结果如下:
# a      NaN
# b    1.300
# c      NaN
# d   -0.275
sum,mean等约简方法的选项:
选项 说明
axis 约简的轴。DataFrame的行axis=0,列用1(axis=1)
skipna 排除缺失值,默认值为True

level 如果轴是层次化索引的(即MultiIndex),则根据level分组约简

(1)有些方法(如idxmin,idmax)返回的是间接统计(比如达到最小值和最大值的索引)
print df.idxmax()
#输出结果如下:
# one    b
# two    d
#另一些方法则是累计型的:
print df.cumsum()
#输出结果如下:
#     one  two
# a  1.40  NaN
# b  8.50 -4.5
# c   NaN  NaN
# d  9.25 -5.8
(2)还有一种方法,它即不是约简型也不是累计型。如dexcribe用于一次性产生多个汇总统计
print df.describe()
#输出结果如下:
#             one       two
# count  3.000000  2.000000
# mean   3.083333 -2.900000
# std    3.493685  2.262742
# min    0.750000 -4.500000
# 25%    1.075000 -3.700000
# 50%    1.400000 -2.900000
# 75%    4.250000 -2.100000
# max    7.100000 -1.300000
(3)对于非数值型数据,describe会产生另外一种汇总统计
obj=Series(['a','a','b','c']*4)
print obj.describe()
#输出结果如下:
# count     16
# unique     3
# top        a
# freq       8
描述和汇总统计:
方法 说明
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 计算百分数变化


相关系数和协方差:

#有些汇总统计(如相关系数和协方差)是通过参数对计算出来的。
import pandas.io.data as web


all_data={}
for ticker in ['AAPL','IBM','MSFT','GOOG']:
    all_data[ticker]=web.get_data_yahoo(ticker,'1/1/2000','1/1/2018')
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()})
print volume
returns=price.pct_change
print returns.tail()

#Series的corr方法用于计算两个Series中重叠的、非NA的、按索引对齐的值的相关系数,cov用于计算协方差
print returns.MSFT.corr(returns.IBM)
print returns.MSFT.cov(returns.IBM)
print returns.corr()  #DataFrame的corr和cov方法将DataFrame的形式返回完整的相关系数和协方差矩阵
#利用DataFrame的corrwith方法,可以计算其列或行跟另一个Series或DataFrame之间的相关系数。
#传入一个Series将会返回一个相关系数值Series(针对各列进行计算)。
print returns.corrwith(returns.IBM)
#传入一个DataFrame则会计算按列名配对的相关系数。这里,我计算百分比变化与成交量的相关系数
print returns.corrwith(volume)  #传入axis=1即可按行进行计算
#在计算相关系数之前,所有的数据项都会按标签对齐。

唯一值、值计数以及成员资格:

还有一类方法可以从一维Series值中抽取信息。
#(1) unique() 去重复值
obj=Series(['c','a','d','a','a','b','b','c','c'])
uniques=obj.unique()
print uniques
#输出结果如下:
# ['c' 'a' 'd' 'b']
#还可以对返回的值进行排序用:sort()
print uniques.sort()
#(2)value_counts用于计算一个Series中各值出现的频率,它是按值降序排序的
print obj.value_counts()
#输出结果如下:
# c    3
# a    3
# b    2
# d    1
#value_counts还是一个顶级pandas方法,可用于任何数组或序列
print pd.value_counts(obj.values,sort=False) #sort=False升序排序
#输出结果如下:
# a    3
# c    3
# b    2
# d    1
#(3)isin,它用于判断矢量化集合的成员资格,可用于选取Series中或DataFrame列中数据的子集
mask=obj.isin(['b','c'])
print mask
#输出结果如下:
# 0     True
# 1    False
# 2    False
# 3    False
# 4    False
# 5     True
# 6     True
# 7     True
# 8     True
print obj[mask]  #mask是布尔值,故是True的值取出
#输出结果如下:
# 0    c
# 5    b
# 6    b
# 7    c
# 8    c
唯一值、值计数以及成员资格方法
方法 说明
isin 计算一个表示“Series各值是否包含于传入的值序列中”的布尔型数组
unique 计算Series中的唯一值数组,按发现的顺序返回
value_counts 返回一个Series,其索引为唯一值,其值为频率,按计数值降序排序
#若希望得到DataFrame中多个相关列的一张柱状图
data=DataFrame({'Qu1':[1,3,4,3,4],
                'Qu2':[2,3,1,2,3],
                'Qu3':[1,5,2,4,4]})
print data
#输出结果如下:
#    Qu1  Qu2  Qu3
# 0    1    2    1
# 1    3    3    5
# 2    4    1    2
# 3    3    2    4
# 4    4    3    4
#将pandas.value_counts传给DataFrame的apply函数
result=data.apply(pd.value_counts)
print result
#输出结果如下:
#    Qu1  Qu2  Qu3
# 1  1.0  1.0  1.0
# 2  NaN  2.0  1.0
# 3  2.0  2.0  NaN
# 4  2.0  NaN  2.0
# 5  NaN  NaN  1.0
result=data.apply(pd.value_counts).fillna(0)
print result
#输出结果如下:
#    Qu1  Qu2  Qu3
# 1  1.0  1.0  1.0
# 2  0.0  2.0  1.0
# 3  2.0  2.0  0.0
# 4  2.0  0.0  2.0
# 5  0.0  0.0  1.0

17.缺失数据处理

import numpy as np
from pandas import Series,DataFrame
import pandas as pd

#(1)pandas使用浮点值NaN表示浮点和非浮点数组中的缺失数据
string_data=Series(['aardvark','artichoke',np.nan,'avocado'])
print string_data
#输出结果如下:
# 0     aardvark
# 1    artichoke
# 2          NaN
# 3      avocado
# dtype: object
print string_data.isnull()
#输出的结果如下:
# 0    False
# 1    False
# 2     True
# 3    False
# dtype: bool
#(2)python内置的None值也会被当做NA处理
string_data[0]=None
print string_data.isnull()
#输出结果如下:
# 0     True
# 1    False
# 2     True
# 3    False
# dtype: bool
NA处理方法:
方法 说明
dropna 根据各标签的值中是否存在缺失数据对轴标签进行过滤,可通过阈值调节对缺失值的容忍度
fillna 用指定值或插值方法(如ffill或bfill)填充缺失数据
isnull 返回一个含有布尔值的对象,这些布尔值表示哪些值是缺失值NA,该对象的类型与源类型一样

notnull isnull的否定式


过滤掉缺失数据的办法有很多种。纯手工操作方法永远是一个办法,但dropna可能会更实用一些。

Series过滤掉缺失数据的方法如下:
(1)dropna
#对于一个Series,dropna返回一个仅含非空数据和索引值的Series.
from numpy import nan as NA
data=Series([1,NA,3.5,NA,7])
print data.dropna()
#输出结果如下:
# 0    1.0
# 2    3.5
# 4    7.0
# dtype: float64
(2)通过布尔型索引达到目的:notnull
print data[data.notnull()]  #data.notnull返回布尔型,True为不为空的值。data[True]取出data中为True的值
#输出的结果如下:
# 0    1.0
# 2    3.5
# 4    7.0
# dtype: float64
DataFrame过滤掉缺数据方法如下:
DataFrame你可能希望丢弃全NA或者含有NA的行或列
(1) dropna默认丢弃任何含有缺失值的行,如果只想丢弃全为NA的那些行,则传入参数how='all'
data=DataFrame([[1.,6.5,3.],[1.,NA,NA],
               [NA,NA,NA],[NA,6.5,3.]])
cleaned=data.dropna()
print data
#输出结果哪下:
# 0    1    2
# 0  1.0  6.5  3.0
# 1  1.0  NaN  NaN
# 2  NaN  NaN  NaN
# 3  NaN  6.5  3.0
print cleaned
#输出结果如下:
#      0    1    2
# 0  1.0  6.5  3.0
print data.dropna(how='all')
#输出的结果如下:
#      0    1    2
# 0  1.0  6.5  3.0
# 1  1.0  NaN  NaN
# 3  NaN  6.5  3.0
(2)要用dropna这种方式丢弃列,只需传入axis=1即可:
data[4]=NA
print data
#输出结果如下:
#      0    1    2   4
# 0  1.0  6.5  3.0 NaN
# 1  1.0  NaN  NaN NaN
# 2  NaN  NaN  NaN NaN
# 3  NaN  6.5  3.0 NaN
print data.dropna(axis=1,how='all')  #axis=1表示列,how='all'这一列全是NaN的
#输出结果如下:
#      0    1    2
# 0  1.0  6.5  3.0
# 1  1.0  NaN  NaN
# 2  NaN  NaN  NaN
# 3  NaN  6.5  3.0
(3)另一个滤除DataFrame行的问题涉及时间序列数据。假设你只想留下一部分观测数据,可以用thresh参数实现
df=DataFrame(np.random.randn(7,3))
df.ix[:4,1]=NA  #:4从下标到4行,1表示下标为1的列即第2列
print df
#输出结果如下:
#           0         1         2
# 0 -1.059619       NaN  1.958930
# 1 -0.551849       NaN -0.072130
# 2 -0.372930       NaN  0.835485
# 3 -0.537468       NaN  0.610045
# 4  0.381160       NaN -1.121259
# 5 -0.993335  0.078202 -0.108020
# 6  0.032738 -1.469338  0.125924
print df.dropna(thresh=3)  #留下没有Nan的数据
#thresh指的是列,只能是3,这个例子若是thresh=2无结果,
# thresh=4报Empty DatatFrme,Columns: [0, 1, 2]
#输出结果如下:
#           0         1         2
# 5 -0.993335  0.078202 -0.108020
# 6  0.032738 -1.469338  0.125924

填充缺失数据:
你可能不想滤除缺失数据(有可能丢弃跟它有关的其它数据),而是希望通过其他方式填补那些“空洞”。

对于大多数情况而言,fillna方法是最主要的函数。通过一个常数调用fillna就会将缺失值替换为那个常数值。

(1)fillna的应用
(1)fillna()填充指定值
print df.fillna(0)
#输出结果如下:
#           0         1         2
# 0  0.435719  0.000000  0.403724
# 1 -1.320617  0.000000  0.044588
# 2  0.624846  0.000000  0.171051
# 3 -0.968712  0.000000  1.402204
# 4  1.222497  0.000000 -1.486042
# 5  0.106718  0.579158  0.064224
# 6 -1.301850  0.076622  0.956990
(2)若是通过一个字典调用fillna,就可以实现对不同的列填充不同的值
print df.fillna({1:0.5,3:-1}) #下标为1的列填充0.5,下标为3的列填充为-1
#输出结果如下:
#           0         1         2
# 0  0.435719  0.500000  0.403724
# 1 -1.320617  0.500000  0.044588
# 2  0.624846  0.500000  0.171051
# 3 -0.968712  0.500000  1.402204
# 4  1.222497  0.500000 -1.486042
# 5  0.106718  0.579158  0.064224
# 6 -1.301850  0.076622  0.956990
(3)fillna默认会返回新对象,但也可以对现有对象进行就地修改
#总是返回被填充对象的引用
_=df.fillna(0,inplace=True)
print df
#输出结果如下:
#           0         1         2
# 0  0.435719  0.000000  0.403724
# 1 -1.320617  0.000000  0.044588
# 2  0.624846  0.000000  0.171051
# 3 -0.968712  0.000000  1.402204
# 4  1.222497  0.000000 -1.486042
# 5  0.106718  0.579158  0.064224
# 6 -1.301850  0.076622  0.956990
(4)对reindex有效的那些插值方法也可用于fillna
df=DataFrame(np.random.randn(6,3))
df.ix[2:,1]=NA #下标为2即从第3行开始,1表示下标为1的即第2列都为NaN
df.ix[4:,2]=NA
print df
#输出结果如下:
#           0         1         2
# 0  0.251605 -1.470314  0.724193
# 1 -1.654733 -0.169537 -0.773023
# 2  0.294954       NaN  0.126516
# 3  1.918257       NaN -0.154707
# 4  0.978893       NaN       NaN
# 5  0.443479       NaN       NaN
print df.fillna(method='ffill') #向前填充,即和前面的值一样
#输出结果如下:
#           0         1         2
# 0  0.251605 -1.470314  0.724193
# 1 -1.654733 -0.169537 -0.773023
# 2  0.294954 -0.169537  0.126516
# 3  1.918257 -0.169537 -0.154707
# 4  0.978893 -0.169537 -0.154707
# 5  0.443479 -0.169537 -0.154707
print df.fillna(method='ffill',limit=2) #只限制2条数据向前填充,其它的还是NaN
#输出结果如下:
#           0         1         2
# 0  0.251605 -1.470314  0.724193
# 1 -1.654733 -0.169537 -0.773023
# 2  0.294954 -0.169537  0.126516
# 3  1.918257 -0.169537 -0.154707
# 4  0.978893       NaN -0.154707
# 5  0.443479       NaN -0.154707
(5)只要稍微动动脑子,就可以利用fillna实现许多别的功能。
#比如说,可以传入Series的平均值或中位数
data=Series([1.,NA,3.5,NA,7])
print data.fillna(data.mean())
#输出结果如下:
# 0    1.000000
# 1    3.833333
# 2    3.500000
# 3    3.833333
# 4    7.000000
# dtype: float64

fillna函数的参数:
参数 说明
value 用于填充缺失值的标量值或字典对象
method 插值方式。如果函数调用时未指定其他参数的话,默认为“ffill”(向前填充)
axis 待填充的轴,默认axis=0(axis=0行,axis=1列)
inplace 修改调用者对象而不产生副本
limit (对于前向和后向填充)可以连续填充的最大数量

18.层次化索引

层次化索引是pandas的一项重要功能,它使你能在一个轴上拥有多个(两个以上)索引级别。

它使你能以低维度形式处理高维度数据。

Series层次化索引:

import numpy as np
from pandas import Series,DataFrame
from numpy import nan as NA
import pandas as pd


df=DataFrame(np.random.randn(7,3))
df.ix[:4,1]=NA
#层次化索引
data=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]])
print data
#输出结果如下:
# a  1    0.284752
#    2   -0.480090
#    3   -0.171065
# b  1   -0.672707
#    2   -1.553886
#    3   -2.647718
# c  1    0.913590
#    2    0.279225
# d  2   -0.550275
#    3    0.444103


(1)这就是带有MultiIndex(双索引)索引的Series的格式化输出形式。索引之间的"间隔"表示"直接使用上面的标签"
print data.index
#输出结果如下:
# MultiIndex(levels=[[u'a', u'b', u'c', u'd'], [1, 2, 3]],
#            labels=[[0, 0, 0, 1, 1, 1, 2, 2, 3, 3], [0, 1, 2, 0, 1, 2, 0, 1, 1, 2]])


(2)对于一个层次化索引的对象,选取数据子集的操作
print data['b']
#输出结果如下:
# 1   -0.672707
# 2   -1.553886
# 3   -2.647718
print data['b':'c'] #索引切片包含右侧,若下标切片和python一样不包含右侧
#输出结果如下:
# b  1   -0.672707
#    2   -1.553886
#    3   -2.647718
# c  1    0.913590
#    2    0.279225
print data.ix[['b','d']]
#输出结果如下:
# b  1   -0.672707
#    2   -1.553886
#    3   -2.647718
# d  2   -0.550275
#    3    0.444103


(3)还可以在"内层"中进行选取
print data[:,2]
#输出结果如下:
# a   -0.480090
# b   -1.553886
# c    0.279225
# d   -0.550275

DataFrame层次化索引:

层次化索引在数据重塑和基于分组的操作(如透视表生成)中扮演着重要的角色。
比如说,这段数据可以通过其unstack方法被重新安排到一个DataFrame中
(1)unstack与stack
print data.unstack()
#输出结果如下:
#           1         2         3
# a  0.879771  0.928296 -1.305827
# b -1.236556  1.285491  1.213506
# c -1.422645  1.176860       NaN
# d       NaN -0.454782 -1.567219
#unstack的逆运算是stack:
print data.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']])
print frame
#输出结果如下:
#      Ohio     Colorado
#     Green Red    Green
# a 1     0   1        2
#   2     3   4        5
# b 1     6   7        8
#   2     9  10       11



(2)各层都可以有名字(可以是字符串,也可以是别的python对象)。如果指定了名称,它们就会显示在控制台输出中(不要将索引名称
# 跟轴标签混为一谈# )。
frame.index.names=['key1','key2']
frame.columns.names=['state','color']
print frame
#输出结果如下:
# state      Ohio     Colorado
# color     Green Red    Green
# key1 key2
# a    1        0   1        2
#      2        3   4        5
# b    1        6   7        8
#      2        9  10       11



(3)由于有了部分的列索引,因此可以轻松选取列分组
print frame['Ohio']
#输出结果如下:
# color      Green  Red
# key1 key2
# a    1         0    1
#      2         3    4
# b    1         6    7
#      2         9   10
重排分级顺序:
有时需要重新调整某条轴上各级别的顺序,或根据指定级别上的值对数据进行排序。

swaplevel接受两个级别编号或名称,并返回一个互换了级别的新对象(但数据不会发生变化),

(1)swaplevel 索引互换

print frame.swaplevel('key1','key2')
#输出的结果如下:
# state      Ohio     Colorado
# color     Green Red    Green
# key2 key1
# 1    a        0   1        2
# 2    a        3   4        5
# 1    b        6   7        8
# 2    b        9  10       11

(2)sortlevel :对索引级别进行排序

sortlevel则根据单个级别中的值对数据进行排序(稳定的)。交换级别时,常常也会用到sortlevel,这样最终结果就是有序的了。
print frame.sortlevel(1) #按第2个索引值排序,即key2
#输出结果如下:
# state      Ohio     Colorado
# color     Green Red    Green
# key1 key2
# a    1        0   1        2
# b    1        6   7        8
# a    2        3   4        5
# b    2        9  10       11
print frame.swaplevel(0,1).sortlevel(0) #swaplevel(0,1)是把0列和1列互换,然后sortlevel(0)按第1列排序
#输出结果如下:
# state      Ohio     Colorado
# color     Green Red    Green
# key2 key1
# 1    a        0   1        2
#      b        6   7        8
# 2    a        3   4        5
#      b        9  10       11

根据级别汇总统计:

许多对DataFrame和Series的描述和汇总统计都有一个level选项,它用于指定在某条轴上求和的级别。我们以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']])
print frame
#输出结果如下:
#      Ohio     Colorado
#     Green Red    Green
# a 1     0   1        2
#   2     3   4        5
# b 1     6   7        8
#   2     9  10       11

frame.index.names=['key1','key2']
frame.columns.names=['state','color']
print frame
#输出结果如下:
# state      Ohio     Colorado
# color     Green Red    Green
# key1 key2
# a    1        0   1        2
#      2        3   4        5
# b    1        6   7        8
#      2        9  10       11
#许多对DataFrame和Series的描述和汇总统计都有一个level选项,它用于指定在某条轴上求和的级别。
print frame.sum(level='key2') #将key2列的值求和
#输出结果如下:
# state  Ohio     Colorado
# color Green Red    Green
# key2
# 1         6   8       10
# 2        12  14       16
print frame.sum(level='color',axis=1) #按color的行求行,且axis=1是列
#输出结果如下:
# color      Green  Red
# key1 key2
# a    1         2    1
#      2         8    4
# b    1        14    7
#      2        20   10
#这其实是用了pandas的groupby功能。
使用DataFrame的列:

有时想要将DataFrame的一个或多个列当做行索引来用,或者可能希望将行索引变成DataFrame的列。

frame=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]})
print frame
#输出结果如下:
#    a  b    c  d
# 0  0  7  one  0
# 1  1  6  one  1
# 2  2  5  one  2
# 3  3  4  two  0
# 4  4  3  two  1
# 5  5  2  two  2
# 6  6  1  two  3
#(1)set_index函数会将其一个或多个列转换为行索引,并创建一个新的DataFrame
frame2=frame.set_index(['c','d'])
print frame2
#输出结果如下:
#        a  b
# c   d
# one 0  0  7
#     1  1  6
#     2  2  5
# two 0  3  4
#     1  4  3
#     2  5  2
#     3  6  1
#默认情况下,加上drop=False 那些列会从DataFrame中移除,但也可以将其保留下来
print frame.set_index(['c','d'],drop=False)
#输出结果如下:
#        a  b    c  d
# c   d
# one 0  0  7  one  0
#     1  1  6  one  1
#     2  2  5  one  2
# two 0  3  4  two  0
#     1  4  3  two  1
#     2  5  2  two  2
#     3  6  1  two  3
#(2)reset_index的功能跟set_index刚好相反,层次化索引的级别会被转移到列里面
print frame2.reset_index()
#输出结果如下:
#      c  d  a  b
# 0  one  0  0  7
# 1  one  1  1  6
# 2  one  2  2  5
# 3  two  0  3  4
# 4  two  1  4  3
# 5  two  2  5  2
# 6  two  3  6  1

19.pandas的整数索引和面板数据

import numpy as np
from pandas import Series,DataFrame
from numpy import nan as NA
import pandas as pd
import pandas.io.data as web

#整数索引
ser=Series(np.arange(3.))
# print ser[-1]  #会报错
#在这种情况下,虽然pandas会"求助于"整数索引,但没有哪种方法能够既不引入任何bug又有效地解决该问题
#这里,我们有一个含有0,1,2的索引,但是很难推断出用户想要什么
print ser
#输出结果哪下:
# 0    0.0
# 1    1.0
# 2    2.0
# dtype: float64
#对于一个非整数索引,就没有这样的歧义
ser2=Series(np.arange(3.),index=['a','b','c'])
print ser2[-1]  #输出结果:2.0
print ser.ix[:1]
#输出结果如下:
# 0    0.0
# 1    1.0
# value 方法和DataFrame的irow和icol方法
ser3=Series(range(3),index=[-5,1,3])
# print ser3.iget_value(2)

frame=DataFrame(np.arange(6).reshape(3,2),index=[2,0,1])
print frame
print frame.irow(0)

#面板数据
pdata=pd.Panel(dict((stk,web.get_data_yahoo(stk,'1/1/2009','6/1/2012'))
                    for stk in ['AAPL','GOOG','MSFT','DELL']))
print pdata

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值