数据分析和大发888平台出租haozbbs.comQ1446595067建模方面的大量编程工作都是用在数据准备上的:加载、清理、转换以及重塑。
许多人选择使用通用编程语言或unix文本处理工具(如sed或awk)对数据格式进行专门处理。
幸运的是,pandas和python标准库提供了一组高级的、灵活的、高效的核心函数和算法,将数据规整化正确的形式。
- 合并数据集:
pandas对象中的数据可以通过一些内置的方式进行合并:
(1)pandas.merge可根据一个名多个键将不同DataFrame中的行连接起来。sql关系型数据库也有merge法,它是用merge实现的就是数据库的连接操作(inner内连接交集,outer外连接,左连接,右连接=>并集)。
(2)pandas.concat可以沿着一条轴将多个对象堆叠到一起。
(3)实例方法combine_first可以将重复数据编接在一起,用一个对象中的值填充另一个对象中的缺失值。
下面分别讲解这些方法:
数据库风格的DataFrame合并:
数据集的合并(merge)或连接(join)运算是通过一个或多个键将行连接起来的。这些运算是关系型数据库的核心。
pandas的merge函数是对数据应用这些算法的主要切入点。
(1)merge的用法
import pandas as pd
import numpy as np
from pandas import Series,DataFrame
df1=DataFrame({‘key‘:[‘b‘,‘b‘,‘a‘,‘c‘,‘a‘,‘a‘,‘b‘],
‘data1‘:range(7)})
df2=DataFrame({‘key‘:[‘a‘,‘b‘,‘d‘],
‘data2‘:range(3)})
print df1
#输出结果如下:
# data1 key
# 0 0 b
# 1 1 b
# 2 2 a
# 3 3 c
# 4 4 a
# 5 5 a
# 6 6 b
# print df2
# #输出结果如下:
# data2 key
# 0 0 a
# 1 1 b
# 2 2 d
(1)这是一种多对一的合并:df1中的数据有多个被标记为a和b行,而df2中key列的每个值则仅对应一行。
这些对象调用merge即可得到
print pd.merge(df1,df2)
#输出结果如下:
# data1 key data2
# 0 0 b 1
# 1 1 b 1
# 2 6 b 1
# 3 2 a 0
# 4 4 a 0
# 5 5 a 0
# #注意:上面的例子并没有指明要用哪个列进行连接。如果没有指定,merge就会将重叠列的列名当做键。
(2)下面指定列:用能数on=
# print pd.merge(df1,df2,on=‘key‘) #输出结果与上面一样
(3)如果两个对象的列名不同,也可以分别进行指定:left_on,right_on
df3=DataFrame({‘lkey‘:[‘b‘,‘b‘,‘a‘,‘c‘,‘a‘,‘a‘,‘b‘],
‘data1‘:range(7)})
df4=DataFrame({‘rkey‘:[‘a‘,‘b‘,‘d‘],
‘data2‘:range(3)})
print pd.merge(df3,df4,left_on=‘lkey‘,right_on=‘rkey‘)
#输出结果如下:
# data1 lkey data2 rkey
# 0 0 b 1 b
# 1 1 b 1 b
# 2 6 b 1 b
# 3 2 a 0 a
# 4 4 a 0 a
# 5 5 a 0 a
#
#注意:结果里面c和d以及与之相关的数据消失了。默认情况下,merge做的是"inner"连接:结果中的键是交集。
# 而其它外连接left,right,outer求取的是键的并集,组合了左连接和右连接的效果。
(4) outer外连接:并集,两个数据Key都要
# print pd.merge(df1,df2,how=‘outer‘) #外连接,两边的key都要传入
# #输出结果如下:并集,df1,df2所有的值都放入
# # data1 key data2
# # 0 0.0 b 1.0
# # 1 1.0 b 1.0
# # 2 6.0 b 1.0
# # 3 2.0 a 0.0
# # 4 4.0 a 0.0
# # 5 5.0 a 0.0
# # 6 3.0 c NaN
# # 7 NaN d 2.0
(5) left左连接:并集,左连接是以左边的为主
# print pd.merge(df1,df2,on=‘key‘,how=‘left‘) #左连接
# #输出结果如下: 左连接是以左边的为主,即df1为主,顾只有df1的key
# # data1 key data2
# # 0 0 b 1.0
# # 1 1 b 1.0
# # 2 2 a 0.0
# # 3 3 c NaN
# # 4 4 a 0.0
# # 5 5 a 0.0
# # 6 6 b 1.0
(6)right右连接:并集,右连接是以右边的为主
# print pd.merge(df1,df2,how=‘right‘) #右连接
# #输出结果如下:右连接,以df2的为主,顾只有df2的key,其它的值是全部写入
# # data1 key data2
# # 0 0.0 b 1
# # 1 1.0 b 1
# # 2 6.0 b 1
# # 3 2.0 a 0
# # 4 4.0 a 0
# # 5 5.0 a 0
# # 6 NaN d 2
(7)inner内连接:交集,默认就是内连接
# print pd.merge(df1,df2,how=‘inner‘) #即merge默认情况下是inner,inner是交集
# #输出结果如下:取df1,df2都有key
# # data1 key data2
# # 0 0 b 1
# # 1 1 b 1
# # 2 6 b 1
# # 3 2 a 0
# # 4 4 a 0
# # 5 5 a 0
(8)若多个键要进行合并,传入一个由列名组成的列表即可
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‘],
‘rval‘:[4,5,6,7]})
print left
#输出结果如下:
# key1 key2 lval
# 0 foo one 1
# 1 foo two 2
# 2 bar one 3
print right
#输出结果如下:
# key1 key2 rval
# 0 foo one 4
# 1 foo one 5
# 2 bar one 6
# 3 bar two 7
print pd.merge(left,right,on=[‘key1‘,‘key2‘],how=‘outer‘)
#输出结果如下:看key1,key2两个键对应的lval的值。外连接,即所有的key都要。
#right中的key组合[foo,one],[foo,one],[foo,two]...用right的key看left有没有。
# key1 key2 lval rval
# 0 foo one 1.0 4.0
# 1 foo one 1.0 5.0
# 2 foo two 2.0 NaN
# 3 bar one 3.0 6.0
# 4 bar two NaN 7.0
(9)合并运算需要考虑对重复列名的处理,merge有一个实用的suffixes选项,用于指定附加到左右两个DataFrame对象的重叠列名上的字符串。
print pd.merge(left,right,on=‘key1‘) #只用单个key,它就有单个key1分别和left,right的key2的组合
#输出结果如下:
# key1 key2_x lval key2_y rval
# 0 foo one 1 one 4
# 1 foo one 1 one 5
# 2 foo two 2 one 4
# 3 foo two 2 one 5
# 4 bar one 3 one 6
# 5 bar one 3 two 7
print pd.merge(left,right,on=‘key1‘,suffixes=(‘_left‘,‘_right‘))
#输出结果如下:
# key1 key2_left lval key2_right rval
# 0 foo one 1 one 4
# 1 foo one 1 one 5
# 2 foo two 2 one 4
# 3 foo two 2 one 5
# 4 bar one 3 one 6
# 5 bar one 3 two 7
merger函数的参数
参数 说明
left 参与合并的左侧DataFrame
right 参与合并的右侧DataFrame
how “inner”、“outer”、“left”、“right”其中之一。默认为"inner"(交集),其它为并集
on 用于连接的列名。必须存在于左右两个DataFrame对象中。如果未指定,且其它连接键也未指定,由以
left和right列名的交集作为连接键
left_on 左侧DataFrame中用作连接键的列
right_on 右侧DataFrame中用作连接键的列
left_index 将左侧的行索引用作其连接键
righgt_index 将右侧的行索引用作其连接键
sort 根据连接键对合并后的数据进行排序,默认为True.有时处理大数据集时,禁用该选项可获得更好的性能
suffixes 字符串值元组,用于追加到重叠列名的末尾,默认为(‘_x‘,‘_y‘).
copy 设置为False,可以在某些特殊情况下避免将数据复制到结果数据结构中。默认总是复制。
索引上DataFrame的合并:
DataFrame中的连接键位于其索引中。在这种情况下,可以传入left_index=True或right_index=True(或两个都传)
以说明索引应该被用作连接键。
(1)merge的用法:索引上合并用left_index=True、right_index=True
import pandas as pd
import numpy as np
from pandas import Series,DataFrame
(1)DataFrame中的连接键位于其索引中:left_index=True或right_index=True(或两个都传)来说明索引应该被用作连接键。
left1=DataFrame({‘key‘:[‘a‘,‘b‘,‘a‘,‘a‘,‘b‘,‘c‘],
‘value‘:range(6)})
right1=DataFrame({‘group_val‘:[3.5,7]},index=[‘a‘,‘b‘])
print left1
#输出结果如下:
# key value
# 0 a 0
# 1 b 1
# 2 a 2
# 3 a 3
# 4 b 4
# 5 c 5
print right1
#输出结果如下:
# group_val
# a 3.5
# b 7.0
print pd.merge(left1,right1,left_on=‘key‘,right_index=True)
#输出结果如下:
# key value group_val
# 0 a 0 3.5
# 2 a 2 3.5
# 3 a 3 3.5
# 1 b 1 7.0
# 4 b 4 7.0
(2)由于默认的merge方法是求取连接键的交集,因此可以通过外连接的方式得到它们的并集。how=‘outer‘
print pd.merge(left1,right1,left_on=‘key‘,right_index=True,how=‘outer‘)
#输出结果如下:
# key value group_val
# 0 a 0 3.5
# 2 a 2 3.5
# 3 a 3 3.5
# 1 b 1 7.0
# 4 b 4 7.0
# 5 c 5 NaN
(3)层次化索引,多层行/列索引
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‘])
print lefth
#输出结果如下:
# data key1 key2
# 0 0.0 Ohio 2000
# 1 1.0 Ohio 2001
# 2 2.0 Ohio 2002
# 3 3.0 Nevada 2001
# 4 4.0 Nevada 2002
print righth
#输出结果如下:
# event1 event2
# Nevada 2001 0 1
# 2000 2 3
# Ohio 2000 4 5
# 2000 6 7
# 2001 8 9
# 2002 10 11
#必须以列表的形式指明用作合并键的多个列(注意对重复索引值的处理)
#left_on左侧DataFrame作为连接键,即lefth,而索引是right_index,即右侧数据为行索引即righth的行索引为行索引
print pd.merge(lefth,righth,left_on=[‘key1‘,‘key2‘],right_index=True)
#没有how参数,默认是inner连接,即交集,取lefth的[‘key1‘,‘key2‘]的数据与righth的行有交集,即相同的取出
#输出结果如下:
# data key1 key2 event1 event2
# 0 0.0 Ohio 2000 4 5
# 0 0.0 Ohio 2000 6 7
# 1 1.0 Ohio 2001 8 9
# 2 2.0 Ohio 2002 10 11
# 3 3.0 Nevada 2001 0 1
#(4)外连接:how=‘outer‘ 并集
print pd.merge(lefth,righth,left_on=[‘key1‘,‘key2‘],right_index=True,how=‘outer‘)
#输出结果如下:
# data key1 key2 event1 event2
# 0 0.0 Ohio 2000 4.0 5.0
# 0 0.0 Ohio 2000 6.0 7.0
# 1 1.0 Ohio 2001 8.0 9.0
# 2 2.0 Ohio 2002 10.0 11.0
# 3 3.0 Nevada 2001 0.0 1.0
# 4 4.0 Nevada 2002 NaN NaN
# 4 NaN Nevada 2000 2.0 3.0
#(5)用merge同时使用合并双方的索引
left2=DataFrame([[1.,2.],[3.,4.],[5.,6.]],index=[‘a‘,‘c‘,‘e‘],
columns=[‘Ohio‘,‘Nevada‘])
right2=DataFrame([[7.,8.],[9.,10.],[11.,12.],[13,14]],
index=[‘b‘,‘c‘,‘d‘,‘e‘],columns=[‘Missouri‘,‘Alabama‘])
print left2
#输出结果如下:
# Ohio Nevada
# a 1.0 2.0
# c 3.0 4.0
# e 5.0 6.0
print right2
#输出结果如下:
# Missouri Alabama
# b 7.0 8.0
# c 9.0 10.0
# d 11.0 12.0
# e 13.0 14.0
print pd.merge(left2,right2,how=‘outer‘,left_index=True,right_index=True)
#同时使用了left_index,right_index同时合并双方索引,且outer外连接交集
#输出结果如下:
# Ohio Nevada Missouri Alabama
# a 1.0 2.0 NaN NaN
# b NaN NaN 7.0 8.0
# c 3.0 4.0 9.0 10.0
# d NaN NaN 11.0 12.0
# e 5.0 6.0 13.0 14.0
(2)join的用法:索引上合并用left_index=True、right_index=True
DataFrame的一个实例方法Join:更为方便地实现按索引合并。它还可以用于合并多个带有相同或相似索引的DataFrame对象,而不管它们之间有没有重叠的列。
#Join:在连接键上是做左连接
# (1)DataFrame的一个实例方法Join:更为方便地实现按索引合并。不管它们之间有没有重叠的列。
#上面的例子可以编写如下:
print left2.join(right2,how=‘outer‘) #类似python的字符串连接Join
#输出结果如下:
# Ohio Nevada Missouri Alabama
# a 1.0 2.0 NaN NaN
# b NaN NaN 7.0 8.0
# c 3.0 4.0 9.0 10.0
# d NaN NaN 11.0 12.0
# e 5.0 6.0 13.0 14.0
# (2)它还支持DataFrame的索引跟调用者DataFrame的某个列之间的连接(即第一个DataFrame的行索引与第二个DataFrame的列连接)
print left1.join(right1,on=‘key‘)
#输出结果如下:
# key value group_val
# 0 a 0 3.5
# 1 b 1 7.0
# 2 a 2 3.5
# 3 a 3 3.5
# 4 b 4 7.0
# 5 c 5 NaN
#(3)可以向join传入一组DataFrame
another=DataFrame([[7.,8.],[9.,10.],[11.,12.],[16.,17.]],
index=[‘a‘,‘c‘,‘e‘,‘f‘],columns=[‘New York‘,‘Oregon‘])
print another
#输出结果如下:
# New York Oregon
# a 7.0 8.0
# c 9.0 10.0
# e 11.0 12.0
# f 16.0 17.0
print left2.join([right2,another]) #left2左分别连接right2,another
# left2内容如下:
# # Ohio Nevada
# # a 1.0 2.0
# # c 3.0 4.0
# # e 5.0 6.0
# right2内容如下:
# # Missouri Alabama
# # b 7.0 8.0
# # c 9.0 10.0
# # d 11.0 12.0
# # e 13.0 14.0
#left2.join([right2,another])输出结果如下:
# Ohio Nevada Missouri Alabama New York Oregon
# a 1.0 2.0 NaN NaN 7.0 8.0
# c 3.0 4.0 9.0 10.0 9.0 10.0
# e 5.0 6.0 13.0 14.0 11.0 12.0
轴上连接:
另一种数据合并运算也被称作连接、绑定或堆叠。numpy有一个用于合并原始Numpy数组的concatenation函数。concatenate是Numpy的方法,
而concate是pandas的方法。
concatenate连接:
arr=np.arange(12).reshape((3,4))
print arr
#输出的结果如下:
# [[ 0 1 2 3]
# [ 4 5 6 7]
# [ 8 9 10 11]]
print np.concatenate([arr,arr],axis=1) #axis=1是列
#输出的结果如下:
# [[ 0 1 2 3 0 1 2 3]
# [ 4 5 6 7 4 5 6 7]
# [ 8 9 10 11 8 9 10 11]]
concate连接:
# 如果各对象其他轴上的索引不同,那些轴应该是做并集还是交集?
# 结果对象中的分组需要各不相同吗?
# 用于连接的轴axis重要吗?
concate用于解决上面的三个问题,它与concatenate没多大区别,只是多了一些参数
(1)三个没有重叠索引的Series,对这些对象调用concat可以将值和索引粘合在一起
s1=Series([0,1],index=[‘a‘,‘b‘])
s2=Series([2,3,4],index=[‘c‘,‘d‘,‘e‘])
s3=Series([5,6],index=[‘f‘,‘g‘])
print s1
# a 0
# b 1
print s2
# c 2
# d 3
# e 4
print s3
# f 5
# g 6
print pd.concat([s1,s2,s3])
#输出结果如下:
# a 0
# b 1
# c 2
# d 3
# e 4
# f 5
# g 6
(2)默认情况下,concat是在axix=0行上作用的,最终产生一个新的Series.如果传入axis=1,则结果就会变成一个DataFrame(axis=1是列)
#series行向合并,本来series只有行索引,故产生一个新的Series.如果列合并,有几个数组,列不一定相同,所以会产生一个DataFrame
print pd.concat([s1,s2,s3],axis=1)
#输出结果如下:
# 0 1 2
# a 0.0 NaN NaN
# b 1.0 NaN NaN
# c NaN 2.0 NaN
# d NaN 3.0 NaN
# e NaN 4.0 NaN
# f NaN NaN 5.0
# g NaN NaN 6.0
(3)这种情况下,另外一条轴上没有重叠,从索引的有序并集上就可以看出。。传入join=‘inner‘即可得到它们的交集
s4=pd.concat([s1*5,s3])
print pd.concat([s1,s4],axis=1)
#输出结果如下:
# 0 1
# a 0.0 0
# b 1.0 5
# f NaN 5
# g NaN 6
print pd.concat([s1,s4],axis=1,join=‘inner‘)
#输出结果如下:
# 0 1
# a 0 0
# b 1 5
(4)可以通过join_axes指字要在其他轴上使用的索引
print pd.concat([s1,s4],axis=1,join_axes=[[‘a‘,‘c‘,‘b‘,‘e‘]])
#输出结果如下:
# 0 1
# a 0.0 0.0
# c NaN NaN
# b 1.0 5.0
# e NaN NaN
(5)不过有个问题,参与连接的片段在结果中区分不开。假设你想要在连接轴上创建一个层次化索引。使用keys参数即可达到目的
result=pd.concat([s1,s1,s3],keys=[‘one‘,‘two‘,‘three‘])
print result
#输出结果如下:
# one a 0
# b 1
# two a 0
# b 1
# three f 5
# g 6
# dtype: int64
print result.unstack()
#输出结果如下:
# a b f g
# one 0.0 1.0 NaN NaN
# two 0.0 1.0 NaN NaN
# three NaN NaN 5.0 6.0
(6)如果沿着axis=1对Series进行合并,则keys就会成为DataFrame的列头
print pd.concat([s1,s2,s3],axis=1,keys=[‘one‘,‘two‘,‘three‘])
#输出结果如下:
# one two three
# a 0.0 NaN NaN
# b 1.0 NaN NaN
# c NaN 2.0 NaN
# d NaN 3.0 NaN
# e NaN 4.0 NaN
# f NaN NaN 5.0
# g NaN NaN 6.0
(7)同样的逻辑对DataFrame对象也是一样:
df1=DataFrame(np.arange(6).reshape(3,2),index=[‘a‘,‘b‘,‘c‘],
columns=[‘one‘,‘two‘])
df2=DataFrame(5+np.arange(4).reshape(2,2),index=[‘a‘,‘c‘],
columns=[‘three‘,‘four‘])
print pd.concat([df1,df2],axis=1,keys=[‘level1‘,‘level2‘])
#输出结果如下:
# level1 level2
# one two three four
# a 0 1 5.0 6.0
# b 2 3 NaN NaN
# c 4 5 7.0 8.0
(8)如果传入的不是列表而是一个字典,则字黄的键就会被做Keys选项的值。
print pd.concat({‘level1‘:df1,‘level2‘:df2},axis=1)
# level1 level2
# one two three four
# a 0 1 5.0 6.0
# b 2 3 NaN NaN
# c 4 5 7.0 8.0
(9)此外还有两个用于管理层次化索引创建方式的参数:
a:key,names
print pd.concat([df1,df2],axis=1,keys=[‘level1‘,‘level2‘],
names=[‘upper‘,‘lower‘])
#输出的结果如下:
# upper level1 level2
# lower one two three four
# a 0 1 5.0 6.0
# b 2 3 NaN NaN
# c 4 5 7.0 8.0
b:ignore_index=True
df1=DataFrame(np.random.randn(3,4),columns=[‘a‘,‘b‘,‘c‘,‘d‘])
df2=DataFrame(np.random.randn(2,3),columns=[‘b‘,‘d‘,‘a‘])
print df1
print df2
#在这种情况下,传入ignore_index=True即可:
print pd.concat([df1,df2],ignore_index=True)
#输出结果如下:
# a b c d
# 0 -0.540071 -0.225394 -0.851317 -1.638987
# 1 0.163700 1.375732 0.255257 1.290061
# 2 0.787074 0.137692 0.929145 -0.793582
# 3 -0.502263 0.717226 NaN -1.224583
# 4 -0.023067 -0.556030 NaN -0.819273
concat函数的参数
参数 说明
objs 参与连接的pandas对象的列表或字典。唯一必需的参数
axis 指明连接的轴向,默认为0
join “inner”、“outer”其中之一,默认为"outer".指明其他轴向上的索引是按交集(inner)
还是并集(outer)进行合并
join_axes 指明用于其他n-1条轴的索引,不执行并集/交集运算
keys 与连接对象有关的值,用于形成连接轴向上的层次化索引。可以是任意值的列表或数组、元组数组、
数组列表(如果将levels设置成多级数组的话)
levels 指定用作层次化索引各级别上的索引,如果设置了keys的话
names 用于创建分层级别的名称,如果设置了keys和levels的话
verify_integrity 检查结果对象新轴上的重复情况,如果发现则引发异常。默认(False)允许重复
ignore_index 不保留连接轴上的索引,产生一组新索引
合并重叠数据:numpy.where, pd.combine_first
还有一种数据组合问题不能用简单的合并(merge)或连接(concatenation)运算来处理。
比如,可能有索引全部或部分重叠的两个数据集。我们使用Numpy的where函数,它用于表达一种矢量化的if-else:
(1)Numpy的where
import pandas as pd
import numpy as np
from pandas import Series,DataFrame
(1)Numpy的where
a=Series([np.nan,2.5,np.nan,3.5,4.5,np.nan],
index=[‘f‘,‘e‘,‘d‘,‘c‘,‘b‘,‘a‘])
b=Series(np.arange(len(a),dtype=np.float64),
index=[‘f‘,‘e‘,‘d‘,‘c‘,‘b‘,‘a‘])
b[-1]=np.nan
print a
#输出结果如下:
# f NaN
# e 2.5
# d NaN
# c 3.5
# b 4.5
# a NaN
print b
#输出结果如下:
# f 0.0
# e 1.0
# d 2.0
# c 3.0
# b 4.0
# a NaN
print np.where(pd.isnull(a),b,a) #a如果是Nan,则用b的数据代替,否则还是a的值
#输出结果如下:
# [ 0. 2.5 2. 3.5 4.5 nan]
(2)Series有一个combine_first方法,可以实现上面一样的功能,而且会时行数据对齐
print b[:-2].combine_first(a[2:]) #b[:-2]的值若有nan则用a[2:]的值代替。但是b[:-2]是不包括右边的倒数第二个b的,
# 则b的值用第一个4.5
#输出结果如下:
# a NaN
# b 4.5
# c 3.0
# d 2.0
# e 1.0
# f 0.0
#Series的combine_first方法实例:DataFrame也有combine_first方法
s1=pd.Series([1,np.nan])
s2=pd.Series([3,4])
print s1
# 0 1.0
# 1 NaN
print s2
# 0 3
# 1 4
print s1.combine_first(s2) #s1里有nan就换成s2的值
# 0 1.0
# 1 4.0
(3)DataFrame的combine_first也是同上,因此可以将其看做:用参数对象中的数据为调用者对象的缺失数据"打补丁"
df1=DataFrame({‘a‘:[1.,np.nan,5.,np.nan],
‘b‘:[np.nan,2.,np.nan,6.],
‘c‘:range(2,18,4)})
df2=DataFrame({‘a‘:[5.,4.,np.nan,3.,7.],
‘b‘:[np.nan,3.,4.,6.,8.]})
print df1
#输出结果如下:
# a b c
# 0 1.0 NaN 2
# 1 NaN 2.0 6
# 2 5.0 NaN 10
# 3 NaN 6.0 14
print df2
#输出结果如下:
# a b
# 0 5.0 NaN
# 1 4.0 3.0
# 2 NaN 4.0
# 3 3.0 6.0
# 4 7.0 8.0
print df1.combine_first(df2) #用df2里的数据为df1中的数据为nan的数据打补丁
#输出结果如下:
# a b c
# 0 1.0 NaN 2.0
# 1 4.0 2.0 6.0
# 2 5.0 4.0 10.0
# 3 3.0 6.0 14.0
# 4 7.0 8.0 NaN
- 重塑和轴向旋转:
pandas对象中有许多用于重新排列表格型数据的基础运算。这些函数也称作重塑或轴向旋转运算。
(1)stack:将数据的列"旋转"为行。(将DataFrame转换成Series,而Series无stack方法)
(2)unstack:与stack相反的操作,将数据的行“旋转”为列。(将Series转换成DataFrame,DataFrame还是DataFrame)
重塑层次化索引:
层次化索引为DataFrame数据的重排任务提供了一个具有良好一致性的方式。主要功能有以下二个方法:
层次化索引为DataFrame数据的
stack:将数据的列"旋转"为行,将DataFrame转换成Series,Series无stack()方法
unstack:将数据的行"旋转"为列,将Series转换成DataFrame了,DataFrame还是DataFrame
(1)将DataFrame的列旋转为行:DataFrame.stack()
data=DataFrame(np.arange(6).reshape((2,3)),
index=pd.Index([‘Ohio‘,‘Colorado‘],name=‘state‘),
columns=pd.Index([‘one‘,‘two‘,‘three‘],name=‘number‘))
print data
#输出结果如下:
# number one two three
# state
# Ohio 0 1 2
# Colorado 3 4 5
result=data.stack()
print result
# #输出结果如下:
# # state number
# # Ohio one 0
# # two 1
# # three 2
# # Colorado one 3
# # two 4
# # three 5
(2)对于一个层次化索引的Series,可以用unstack将其重排为一个DataFrame.
print result.unstack()
#输出结果如下:
# number one two three
# state
# Ohio 0 1 2
# Colorado 3 4 5
默认情况下,unstack操作的是最内层(stack也是如此)。传入分层级别的编号或名称即可对其他级别进行unstack操作
print result.unstack(0)
#输出结果如下:
# state Ohio Colorado
# number
# one 0 3
# two 1 4
# three 2 5
print result.unstack(‘state‘)
#输出结果如下:
# state Ohio Colorado
# number
# one 0 3
# two 1 4
# three 2 5
(3)如果不是所有级别值都能在各分组中找到的话,则unstack操作可能会引入缺失数据:
s1=Series([0,1,2,3],index=[‘a‘,‘b‘,‘c‘,‘d‘])
s2=Series([4,5,6],index=[‘c‘,‘d‘,‘e‘])
data2=pd.concat([s1,s2],keys=[‘one‘,‘two‘])
print data2
#输出结果如下:
# one a 0
# b 1
# c 2
# d 3
# two c 4
# d 5
# e 6
# dtype: int64
print data2.unstack()
#输出结果如下:
# a b c d e
# one 0.0 1.0 2.0 3.0 NaN
# two NaN NaN 4.0 5.0 6.0
(4)stack默认会滤除缺失数据,因此该运算是可逆的:
# print data2.stack() #报错‘Series‘ object has no attribute ‘stack‘
#可以对data2.unstack()后的DataFrame进行stack()
print data2.unstack().stack(dropna=False) #DataFrame转换成Series了,且列变成行了
#输出结果如下:
# one a 0.0
# b 1.0
# c 2.0
# d 3.0
# e NaN
# two a NaN
# b NaN
# c 4.0
# d 5.0
# e 6.0
print data2.unstack().unstack() #data2.unstack()的行变成列
#输出结果如下:
# a one 0.0
# two NaN
# b one 1.0
# two NaN
# c one 2.0
# two 4.0
# d one 3.0
# two 5.0
# e one NaN
# two 6.0
(5)对DataFrame进行unstack操作时,作为旋转轴的级别将会成为结果中的最低级别
df=DataFrame({‘left‘:result,‘right‘:result+5},
columns=pd.Index([‘left‘,‘right‘],name=‘side‘))
print df
#result的内容如下:
# # state number
# # Ohio one 0
# # two 1
# # three 2
# # Colorado one 3
# # two 4
# # three 5
#df的结果如下:
# side left right
# state number
# Ohio one 0 5
# two 1 6
# three 2 7
# Colorado one 3 8
# two 4 9
# three 5 10
print df.unstack(‘state‘) #将state的行旋转为列
#输出结果如下:
# side left right
# state Ohio Colorado Ohio Colorado
# number
# one 0 3 5 8
# two 1 4 6 9
# three 2 5 7 10
print df.unstack(‘state‘).stack(‘side‘) #将上面的再stack将列为side的旋转为行(即left,right)
#输出结果如下:
# state Colorado Ohio
# number side
# one left 3 0
# right 8 5
# two left 4 1
# right 9 6
# three left 5 2
# right 10 7
将"长格式"转换为"宽格式":
时间序列数据通常是以所谓的"长格式"(long)或"堆叠格式"(stacked)存储在数据库和CSV中的。
关系型数据库通常是主键形式提供了关系的完整性,而且提供了更为简单的查询支持。但对于长格式的数据操作起来就不那么轻松了。
而DataFrame可以把主键中不同的Item值分别形成一列,date列中的时间值则用作索引,可以用DataFrame的pivot方法完全可以实现这个转换。
import pandas as pd
import numpy as np
from pandas import Series,DataFrame
ldata=DataFrame({‘date‘:[‘1959-03-31 00:00:00‘,‘1959-03-31 00:00:00‘,‘1959-03-31 00:00:00‘,
‘1959-06-30 00:00:00‘,‘1959-06-30 00:00:00‘,‘1959-06-30 00:00:00‘,
‘1959-09-30 00:00:00‘,‘1959-09-30 00:00:00‘,‘1959-09-30 00:00:00‘,‘1959-12-31 00:00:00‘],
‘item‘:[‘realgdp‘,‘infl‘,‘unemp‘,‘realgdp‘,‘infl‘,‘unemp‘,‘realgdp‘,‘infl‘,‘unemp‘,‘realgdp‘],
‘value‘:[‘2710.349‘,‘0.000‘,‘5.800‘,‘2778.801‘,‘2.340‘,‘5.100‘,‘2775.488‘,‘2.740‘,‘5.300‘,‘2785.204‘]
})
print ldata
#输出结果如下:
# date item value
# 0 1959-03-31 00:00:00 realgdp 2710.349
# 1 1959-03-31 00:00:00 infl 0.000
# 2 1959-03-31 00:00:00 unemp 5.800
# 3 1959-06-30 00:00:00 realgdp 2778.801
# 4 1959-06-30 00:00:00 infl 2.340
# 5 1959-06-30 00:00:00 unemp 5.100
# 6 1959-09-30 00:00:00 realgdp 2775.488
# 7 1959-09-30 00:00:00 infl 2.740
# 8 1959-09-30 00:00:00 unemp 5.300
# 9 1959-12-31 00:00:00 realgdp 2785.204
(1)使用DataFrame的pivot的方法
pivoted=ldata.pivot(‘date‘,‘item‘,‘value‘)
print pivoted.head()
#输出结果如下:
# item infl realgdp unemp
# date
# 1959-03-31 00:00:00 0.000 2710.349 5.800
# 1959-06-30 00:00:00 2.340 2778.801 5.100
# 1959-09-30 00:00:00 2.740 2775.488 5.300
# 1959-12-31 00:00:00 None 2785.204 None
(2)前两个参数值分别用作行和列索引的列名,最后一个参数值则是用于填充DataFrame的数据列的列名。
#假设有两个需要参与重塑的数据列:
ldata[‘value2‘]=np.random.randn(len(ldata))
print ldata[:10]
#输出结果如下:
# date item value value2
# 0 1959-03-31 00:00:00 realgdp 2710.349 0.935557
# 1 1959-03-31 00:00:00 infl 0.000 1.609324
# 2 1959-03-31 00:00:00 unemp 5.800 -0.753734
# 3 1959-06-30 00:00:00 realgdp 2778.801 -0.668879
# 4 1959-06-30 00:00:00 infl 2.340 -0.256601
# 5 1959-06-30 00:00:00 unemp 5.100 0.537770
# 6 1959-09-30 00:00:00 realgdp 2775.488 1.073817
# 7 1959-09-30 00:00:00 infl 2.740 -0.027340
# 8 1959-09-30 00:00:00 unemp 5.300 -0.531161
# 9 1959-12-31 00:00:00 realgdp 2785.204 0.706080
(3)如果忽略掉最后一个参数,得到的DataFrame就会带有层次化的列
pivoted=ldata.pivot(‘date‘,‘item‘)
print pivoted[:5]
#输出结果如下:
# value value2
# item infl realgdp unemp infl realgdp unemp
# date
# 1959-03-31 00:00:00 0.000 2710.349 5.800 -0.505690 -1.090732 -2.123859
# 1959-06-30 00:00:00 2.340 2778.801 5.100 -0.940028 -2.204997 -1.195357
# 1959-09-30 00:00:00 2.740 2775.488 5.300 -0.636424 0.510898 1.105585
# 1959-12-31 00:00:00 None 2785.204 None NaN -0.203154 NaN
(4)注意,pivot其实只是一个快捷方式而己:用set_index创建层次化索引,再用unstack重塑。
unstacked=ldata.set_index([‘date‘,‘item‘]).unstack(‘item‘)
print unstacked[:7]
#输出结果如下:
# value value2
# item infl realgdp unemp infl realgdp unemp
# date
# 1959-03-31 00:00:00 0.000 2710.349 5.800 -0.380805 -2.499867 -1.398593
# 1959-06-30 00:00:00 2.340 2778.801 5.100 -0.168914 0.435372 -1.454938
# 1959-09-30 00:00:00 2.740 2775.488 5.300 -0.297850 -1.693196 1.615807
# 1959-12-31 00:00:00 None 2785.204 None NaN 1.551105 NaN
import pandas as pd
import numpy as np
from pandas import Series,DataFrame
df = pd.DataFrame({‘foo‘: [‘one‘, ‘one‘, ‘one‘, ‘two‘, ‘two‘,
‘two‘],
‘bar‘: [‘A‘, ‘B‘, ‘C‘, ‘A‘, ‘B‘, ‘C‘],
‘baz‘: [1, 2, 3, 4, 5, 6],
‘zoo‘: [‘x‘, ‘y‘, ‘z‘, ‘q‘, ‘w‘, ‘t‘]})
print df
#输出结果如下:
# bar baz foo zoo
# 0 A 1 one x
# 1 B 2 one y
# 2 C 3 one z
# 3 A 4 two q
# 4 B 5 two w
# 5 C 6 two t
print df.pivot(index=‘foo‘,columns=‘bar‘)[‘baz‘] #行索引foo,列bar,值baz
#输出结果如下:
# bar A B C
# foo
# one 1 2 3
# two 4 5 6
print df.pivot(index=‘foo‘,columns=‘bar‘,values=‘baz‘) #与上面的一致
# print df.pivot(index=‘foo‘,columns=‘bar‘,values=[‘baz‘, ‘zoo‘])
#若是两行的索引一样的话会报错,因为值就不知道对应哪个了
#如下例中bar中的两个索一样
df=pd.DataFrame({"foo":[‘one‘,‘one‘,‘two‘,‘two‘],
"bar":[‘A‘,‘A‘,‘B‘,‘C‘],
"baz":[1,2,3,4]})
print df
print df.pivot(index=‘foo‘,columns=‘bar‘,values=‘baz‘) #报错,foo,bar为[one,A]不知道对应哪个值了,两个一样的索引
- 数据转换:
前面讲的都是数据重排,另一类重要操作则是过滤、清理以及其它的转换工作。
(1)drop_duplicates:删除重复数据
(2)map:函数或映射进行数据转换(map,lambda),map用于修改对象的子集
(3)fillna: 用于填充缺失数据,看做值替换的一种特殊情况。或者用pandas的replace方法替换缺失值(与python的str.replace方法一样)
(4)rename:复制DataFrame并对其行索引和列标签进行修改。若要就地修改某个数据集,传入inplace=True即可
(5)cut:将数据划分阶段(即元面)例不同的年龄阶段,它返回的Categorical对象。而qcut是根据样本分位数对数据进行划分(可以等分)
(6)abs:过滤绝对值,np.abs(data)>3取绝对值>3的数。
(7)np.sign:过滤的区间为-1到1的数组,表示原始值的符号。
(8)take:选取子集,从DataFrame或Series中选取部分子集
(9)get_dummies:DataFrame的某一列中有多个不同的值,可将该列的值作为列名,其值全为1和0.例:第一行只有a的值,则a为1,其它为0
Series只有panda.str.get_dummies.
原文地址:http://blog.51cto.com/13861813/2139742