数据分析学习笔记(三)——Pandas

本文介绍了Pandas在数据分析中的关键操作,包括使用`on`和`index`参数进行数据合并,理解数据合并的集合操作规则如`inner`、`outer`等,以及`groupby`进行数据分组、累计、过滤、转换和应用。此外,还讲解了如何自定义分割数据和使用数据透视表进行多条件分类计算。
摘要由CSDN通过智能技术生成
  1. 使用on与index参数控制数据合并的键

    1. 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方法删除一列
    
    
    
    1. 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
    
    
    
  2. 数据合并中的集合操作规则

由于在数据连接中,在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


  1. 在集合两个具有同名列的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

  1. 运用describe方法对数据集的基本情况做一个概览

pandas内置的describe方法可以对数据集的基本情况有一个大致的了解,包括最大最小值,标准差与方差,平均数等等,但在调用之前需要检查数据集中是否存在有缺失值的情,如果有的话需要调用dropna先清除。

  1. 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

  1. 对数据分组后进行累计,过滤,转换与应用

    1. 累计(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
    
    
    1. 过滤(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
    
    
    1. 转换(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
    
    1. 应用(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
#注意前面的索引,变为了我们自定义的字符串

  1. 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

  1. 简单应用:综合利用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

  1. 数据透视表语法

像上述情况会非常常见,尤其针对两个条件进行分类并计算时,因此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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值