-
使用on与index参数控制数据合并的键
- on
on关键字用以确认合并数据的键,要求两个数据集需有一个相同名称的列,也可以传入一个包含多名称的列名列表。但常见的情况是两个数据集相同的一列用了不同的命名方式,此时就需要用到left_on与right_on。
In [16]: df1 Out[16]: name group 0 lida a 1 coco b 2 joe c 3 sara c In [17]: df2 = pd.DataFrame({'group_name':['a','b','c'],'leader':['zhang','forg','ha']}) In [18]: pd.merge(df1,df2) MergeError Traceback (most recent call last) <ipython-input-18-01b6d59980d6> in <module>() #直接调用merge出现错误 In [19]: pd.merge(df1,df2,left_on='group',right_on='group_name') Out[19]: name group group_name leader 0 lida a a zhang 1 coco b b forg 2 joe c c ha 3 sara c c ha #确定左右合并的键后合并完成,但多余出一列,可以调用drop方法删除一列
- index索引合并
有些时候需要将两个数据集按照索引合并,此时就可以利用left_index与right_index参数,或者直接利用join方法。
In [27]: df1s = df1.set_index('group') In [28]: df2s = df2.set_index('group_name') In [29]: df1s Out[29]: name group a lida b coco c joe c sara In [30]: df2s Out[30]: leader group_name a zhang b forg c ha In [33]: pd.merge(df1s,df2s,left_index=True,right_index=True) Out[33]: name leader a lida zhang b coco forg c joe ha c sara ha In [34]: df1s.join(df2s) Out[34]: name leader a lida zhang b coco forg c joe ha c sara ha
-
数据合并中的集合操作规则
由于在数据连接中,在A中的数据不一定在B中,所以可以在how参数设置四种格式,分别是inner(交集),outer(并集),left(按左集),right(按右集)
In [37]: df1
Out[37]:
name age
0 a 1
1 b 2
2 c 3
In [38]: df2
Out[38]:
name food
0 b fish
1 c rice
2 d chicken
In [41]: pd.merge(df1,df2,how='inner')
Out[41]:
name age food
0 b 2 fish
1 c 3 rice
In [42]: pd.merge(df1,df2,how='outer')
Out[42]:
name age food
0 a 1.0 NaN
1 b 2.0 fish
2 c 3.0 rice
3 d NaN chicken
In [43]: pd.merge(df1,df2,how='left')
Out[43]:
name age food
0 a 1 NaN
1 b 2 fish
2 c 3 rice
In [44]: pd.merge(df1,df2,how='right')
Out[44]:
name age food
0 b 2.0 fish
1 c 3.0 rice
2 d NaN chicken
- 在集合两个具有同名列的DataFrame时,如果他们后面映射的数据不同,系统会为其自动分配后缀,也可以用suffixes参数传入一个名称列表自定,该参数同样适用于多个列。
In [47]: df1
Out[47]:
name age
0 a 1
1 b 2
2 c 3
In [48]: df2
Out[48]:
name age
0 a 4
1 b 3
2 c 6
In [50]: pd.merge(df1,df2,on='name',)
Out[50]:
name age_x age_y
0 a 1 4
1 b 2 3
2 c 3 6
In [51]: pd.merge(df1,df2,on='name',suffixes=['le','ri'])
Out[51]:
name agele ageri
0 a 1 4
1 b 2 3
2 c 3 6
- 运用describe方法对数据集的基本情况做一个概览
pandas内置的describe方法可以对数据集的基本情况有一个大致的了解,包括最大最小值,标准差与方差,平均数等等,但在调用之前需要检查数据集中是否存在有缺失值的情,如果有的话需要调用dropna先清除。
- groupby
pandas的groupby会按照指定的键将数值分组,生成一个groupby对象,可以针对这个对象进行相应的数学计算,并且,其同样支持取值操作。
In [31]: planets.groupby('method')['year'].describe().sort_values(by = 'count',ascending = False)
#按照method特征分组,并取出所有的year列,然后分别计算他们的数学特征。
#group可以简单的理解为 1.分组 2.计算 3.合并 这样三个过程
Out[31]:
count mean std min 25% 50% 75% max
method
Radial Velocity 553.0 2007.518987 4.249052 1989.0 2005.00 2009.0 2011.00 2014.0
Transit 397.0 2011.236776 2.077867 2002.0 2010.00 2012.0 2013.00 2014.0
Imaging 38.0 2009.131579 2.781901 2004.0 2008.00 2009.0 2011.00 2013.0
Microlensing 23.0 2009.782609 2.859697 2004.0 2008.00 2010.0 2012.00 2013.0
Eclipse Timing Variations 9.0 2010.000000 1.414214 2008.0 2009.00 2010.0 2011.00 2012.0
Pulsar Timing 5.0 1998.400000 8.384510 1992.0 1992.00 1994.0 2003.00 2011.0
Transit Timing Variations 4.0 2012.500000 1.290994 2011.0 2011.75 2012.5 2013.25 2014.0
Orbital Brightness Modulation 3.0 2011.666667 1.154701 2011.0 2011.00 2011.0 2012.00 2013.0
Astrometry 2.0 2011.500000 2.121320 2010.0 2010.75 2011.5 2012.25 2013.0
Pulsation Timing Variations 1.0 2007.000000 NaN 2007.0 2007.00 2007.0 2007.00 2007.0
-
对数据分组后进行累计,过滤,转换与应用
- 累计(aggregate)
In [45]: df Out[45]: key data1 data2 0 a 0 6 1 b 1 3 2 c 2 7 3 a 3 4 4 b 4 6 5 c 5 9 In [44]: df.groupby('key').aggregate([min,max]) #按照key分组后,累计求得每组数据每一个特征下的最小最大值 #所以每一个数组列下会有两个子列 Out[44]: data1 data2 min max min max key a 0 3 4 6 b 1 4 3 6 c 2 5 7 9
- 过滤(filter)
In [49]: df.groupby('key')['data2'].std() Out[49]: key a 1.414214 b 2.121320 c 1.414214 Name: data2, dtype: float64 In [50]: df.groupby('key').filter(lambda x: x['data2'].std() < 1.5) #filter会选择使括号中函数式为真的组,过滤掉那些不符合条件的组 Out[50]: key data1 data2 0 a 0 6 2 c 2 7 3 a 3 4 5 c 5 9
- 转换(transform)
类似但不同于累计,转换函数将对每一个数值做一次相同的变换,所以会得到一个与原数组相同形状的新数组,常见的是每个数组减去该数组的均值从而实现数值标准化。
In [52]: df.groupby('key').transform(lambda x : x - x.mean()) Out[52]: data1 data2 0 -1.5 1.0 1 -1.5 -1.5 2 -1.5 -1.0 3 1.5 -1.0 4 1.5 1.5 5 1.5 1.0
- 应用(apply)
存疑
7.对数据进行自定义分割
groupby方法并不单纯只针对于特殊的键,在不指定键的情况下,可以将索引映射到自定义的分组中(利用列表,或者以原索引为键的字典),从而完成自定义分组。
In [58]: df
Out[58]:
key data1 data2
0 a 0 6
1 b 1 3
2 c 2 7
3 a 3 4
4 b 4 6
5 c 5 9
In [59]: li = [0,1,0,0,1,2]
#在这里将自然索引映射到了li中,因此最终会被分为0,1,2三个组
In [62]: df.groupby(li).sum()
Out[62]:
data1 data2
0 5 17
1 5 9
2 5 9
In [67]: df.groupby({'a':'first','b':'second','c':'second'}).sum()
#此处利用字典,将默认的索引a分为first类,b与c归为second类,整体分组后就会变为
#两个组
Out[67]:
data1 data2
first 3 10
second 12 25
#注意前面的索引,变为了我们自定义的字符串
- groupby形成多级列表
若想要分成多类,从而形成一个类矩阵,则可以给groupby中传入一个分类目标列表,其最后的结果是两个目标所形成的笛卡尔积所对应的值。
In [73]: df
Out[73]:
key key_2 data
0 a 1 0
1 b 2 1
2 c 3 2
3 a 2 3
4 b 2 4
5 c 3 5
6 b 4 6
7 c 2 7
In [75]: df.groupby(['key','key_2']).sum()
#先按照key分类,然后在每一个key下继续按照key_2分类,最后输出sum()后的结果
Out[75]:
data
key key_2
a 1 0
2 3
b 2 5
4 6
c 2 7
3 7
- 简单应用:综合利用group语法计算每种不同方法下不同年份发现的行星数量
In [76]: planets
Out[76]:
method number orbital_period mass distance year
0 Radial Velocity 1 269.300000 7.10 77.40 2006
1 Radial Velocity 1 874.774000 2.21 56.95 2008
2 Radial Velocity 1 763.000000 2.60 19.84 2011
3 Radial Velocity 1 326.030000 19.40 110.62 2007
4 Radial Velocity 1 516.220000 10.50 119.47 2009
... ... ... ... ... ... ...
1030 Transit 1 3.941507 NaN 172.00 2006
1031 Transit 1 2.615864 NaN 148.00 2007
1032 Transit 1 3.191524 NaN 174.00 2007
1033 Transit 1 4.125083 NaN 293.00 2008
1034 Transit 1 4.187757 NaN 260.00 2008
#首先针对具体的年份,将其划分到不同的年代中
In [80]: decade = planets['year']//10*10
In [81]: decade
Out[81]:
0 2000
1 2000
2 2010
3 2000
4 2000
...
1030 2000
1031 2000
1032 2000
1033 2000
1034 2000
Name: year, Length: 1035, dtype: int64
In [82]: decade = decade.astype(str)+'s'
#这里注意,直接抽取出来的是一个Series对象,不能直接对其应用str()函数
#而要利用上述的astype方法
In [83]: decade
Out[83]:
0 2000s
1 2000s
2 2010s
3 2000s
4 2000s
...
1030 2000s
1031 2000s
1032 2000s
1033 2000s
1034 2000s
#输出了一个Series对象,其与DataFrame的每一行一一对应
#按照method与我们自定义的年代分组
In [89]: planets.groupby(['method',decade])['number'].sum().unstack().fillna(0)
#将其分成一个类矩阵后,其每一个类中仍然包含需要信息
#我们抽出其中的number项,然后求和,即得到了相应的结果
#最后利用unstack解压多级索引,并利用fillna填充缺省值
Out[89]:
decade 1980s 1990s 2000s 2010s
method
Astrometry 0.0 0.0 0.0 2.0
Eclipse Timing Variations 0.0 0.0 5.0 10.0
Imaging 0.0 0.0 29.0 21.0
Microlensing 0.0 0.0 12.0 15.0
Orbital Brightness Modulation 0.0 0.0 0.0 5.0
Pulsar Timing 0.0 9.0 1.0 1.0
Pulsation Timing Variations 0.0 0.0 1.0 0.0
Radial Velocity 1.0 52.0 475.0 424.0
Transit 0.0 0.0 64.0 712.0
Transit Timing Variations 0.0 0.0 0.0 9.0
- 数据透视表语法
像上述情况会非常常见,尤其针对两个条件进行分类并计算时,因此pandas提供了更为方便的数据透视表语法,对一个数据表调用该方法,传入所需要的列与分类的index和colums,以及相应的操作函数,即可快速完成。
In [112]: titanic.pivot_table('survived',index='sex',columns='class',aggfunc='mean')
#对数据表调用语法,所求为生还值,行坐标为性别,列坐标为仓位,操作函数为平均值
Out[112]:
class First Second Third
sex
female 0.968085 0.921053 0.500000
male 0.368852 0.157407 0.135447