zoukankan      html  css  js  c++  java
  • python数据分析之:数据清理,转换,合并,重塑(一)

    DataFrame合并:
    merge运算是将一个或多个键将行链接起来。来看下面的这个例子:
    In [5]: df1=DataFrame({'key':['b','b','a','c','a','a','b'],'data1':range(7)})
     
    In [6]: df2=DataFrame({'key':['a','b','d'],'data2':range(3)})
     
    In [7]: df1
    Out[7]:  
       data1 key
    0      0   b
    1      1   b
    2      2   a
    3      3   c
    4      4   a
    5      5   a
    6      6   b
     
    In [8]: df2
    Out[8]:  
       data2 key
    0      0   a
    1      1   b
    2      2   d
    df1和df2的key值中都含有a,b,d,不同的是在df1中有重复的key值,而在df2中key值都是唯一的。通过merge函数可以将df1和df2中key值相同的行都链接起来。这种操作就和数据库中的inner join操作是差不多的。因为可以看到在合并后的数据中,key=c和d的列不存在了,因为inner join是取的交集,其他方式还有left,right,outer的方式
    In [9]: pd.merge(df1,df2)
    Out[9]:  
       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
    取并集的方式
    In [15]: pd.merge(df1,df2,how='outer')
    Out[15]:  
       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
     
    但是上面这个merge函数并没有指定对哪个列进行连接,如果没有指定,merge将会将重叠列的列名当做键。df1和df2重叠的键就是key。但是这里最好指定下列的名称。pd.merge(df1,df2,on='key')。注意这里指定列名称的时候,这个列名称必须是在合并数据中都存在的。比如如果指定on=’data1’就会报错,因为在df2中找不到data1的列
     
    但是如果两个对象的列名不一样,也可以分别进行指定
    df3=DataFrame({'lkey':['b','b','a','c','a','a','b'],'data1':r
    ...: ange(7)})
     
    df4=DataFrame({'rkey':['a','b','d'],'data2':range(3)})
    通过left_on和right_on来分别指定列
    In [19]: pd.merge(df3,df4,left_on='lkey',right_on='rkey')
    Out[19]:  
       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
     
    前面讲到默认合并是inner,通过how来制定合并方式,how有outer,left,right三种方式
    In [20]: pd.merge(df1,df2,on='key',how='left')
    Out[20]:  
       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
    right的方式
    In [21]: pd.merge(df1,df2,on='key',how='right')
    Out[21]:  
       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
     
    merge参数

    索引上的合并:

    有时候,DataFrame中的连接键位于其索引中,在这种情况下,你可以传入left_index=Trueright_index=True以说明索引应该被用作连接键

    In [22]: left1=DataFrame({'key':['a','b','a','a','b','c'],'value':rang

        ...: e(6)})

    In [24]: right1=DataFrame({'group_val':[3.5,7]},index=['a','b'])

    In [29]: pd.merge(left1,right1,left_on='key',right_index=True)

    Out[29]: 

      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

    通过这种方法,就把right1group_val的值也一起合并起来了。当然同样的也可以采取并集的方式

    In [30]: pd.merge(left1,right1,left_on='key',right_index=True,how='out

        ...: er')

    Out[30]: 

      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

    再来看下复杂的合并,关于层次化的索引。

    In [32]: left1=DataFrame({'key1':['ohio','ohio','ohio','nevada','nevad

    ...: a'],'key2':[2000,2001,2002,2001,2002],'data':np.arange(5.)})

    In [34]: right1=DataFrame(np.arange(12).reshape((6,2)),index=[['nevada

        ...: ','nevada','ohio','ohio','ohio','ohio'],[2001,2000,2000,2000,

        ...: 2001,2002]],columns=['event1','event2'])

    In [35]: left1

    Out[35]: 

       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

    In [36]: right1

    Out[36]: 

                 event1  event2

    nevada 2001       0       1

           2000       2       3

    ohio   2000       4       5

           2000       6       7

           2001       8       9

           2002      10      11

    对于多层次索引的数据,必须以列表的形式指明用过合作键的多个列,这里指定key1key2

    去并集的方式

    In [40]: pd.merge(left1,right1,left_on=['key1','key2'],right_index=Tru

        ...: e)

    Out[40]: 

       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

    In [44]: pd.merge(left1,right1,left_on=['key1','key2'],right_index=Tru

        ...: e,how='outer')

    Out[44]: 

       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

    也可以合并双方的索引。

    In [45]: left2=DataFrame([[1,2],[3,4],[5,6]],index=['a','c','e'],colum

        ...: ns=['ohio','nevada'])

    In [47]: right2=DataFrame([[7,8],[9,10],[11,12],[13,14]],index=['b','c

        ...: ','d','e'],columns=['missouri','alabama'])

    In [46]: left2

    Out[46]: 

       ohio  nevada

    a     1       2

    c     3       4

    e     5       6

    In [48]: right2

    Out[48]: 

       missouri  alabama

    b         7        8

    c         9       10

    d        11       12

    e        13       1

    将两个数据的所有列的数据全部集合起来。

    In [49]: pd.merge(left2,right2,how='outer',left_index=True,right_index

        ...: =True)

    Out[49]: 

       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

    DataFrame还有一个join实例方法,它能更方便地实现按索引合并,它还可以用于合并多个带有相同或相似索引的DataFrame对象。而不管它们之间有没有重叠的列。对于上面的例子,我们可以join的方法来实现

    In [50]: left2.join(right2,how='outer')

    Out[50]: 

       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

    轴向连接

    轴向连接也可以看做是连接concatenation的操作。

    In [4]: arr=np.arange(12).reshape((3,4))

    In [5]: arr

    Out[5]: 

    array([[ 0,  1,  2,  3],

           [ 4,  5,  6,  7],

           [ 8,  9, 10, 11]])

    In [6]: np.concatenate([arr,arr],axis=1)

    Out[6]: 

    array([[ 0,  1,  2,  3,  0,  1,  2,  3],

           [ 4,  5,  6,  7,  4,  5,  6,  7],

           [ 8,  9, 10, 11,  8,  9, 10, 11]])

    接下来看下pandas中的concat函数。对于pandas对象,由于具备索引,因此连接运算的时候需要考虑索引的连接。

    In [9]: s1=Series([0,1],index=['a','b'])

    In [10]: s1

    Out[10]: 

    a    0

    b    1

    dtype: int64

    In [11]: s2=Series([2,3,4],index=['c','d','e'])

    In [12]: s2

    Out[12]: 

    c    2

    d    3

    e    4

    dtype: int64

    In [13]: s3=Series([5,6],index=['f','g'])

    In [14]: s3

    Out[14]: 

    f    5

    g    6

    dtype: int64

    In [15]: pd.concat([s1,s2,s3])

    Out[15]: 

    a    0

    b    1

    c    2

    d    3

    e    4

    f    5

    g    6

    dtype: int64

    默认情况下,concat是在axis=0上工作的,也就是按照行的方式进行拼接,设置axis=1就可以按照列的方式进行拼接。

    In [16]: pd.concat([s1,s2,s3],axis=1)

    Out[16]: 

         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

    我们还可以通过传入join=’inner’的方式取得并集

    In [17]: s4=pd.concat([s1*5,s3])

    In [18]: s4

    Out[18]: 

    a    0

    b    5

    f    5

    g    6

    dtype: int64

    In [19]: s1

    Out[19]: 

    a    0

    b    1

    dtype: int64

    In [20]: pd.concat([s1,s4],axis=1)

    Out[20]: 

         0  1

    a  0.0  0

    b  1.0  5

    f  NaN  5

    g  NaN  6

    In [21]: pd.concat([s1,s4],axis=1,join='inner')

    Out[21]: 

       0  1

    a  0  0

    b  1  5

    前面在合并s1,s2,s3的时候得到的结果是

    a    0

    b    1

    c    2

    d    3

    e    4

    f    5

    g    6

    如果想层次化分层的话,可以通过设置key值来设置层次化索引

    In [22]: result=pd.concat([s1,s2,s3],keys=['one','two','thress'])

    In [23]: result

    Out[23]: 

    one     a    0

            b    1

    two     c    2

            d    3

            e    4

    thress  f    5

            g    6

    dtype: int64

    In [25]: result=pd.concat([s1,s2,s3],axis=1,keys=['one','two','thress'])

    In [26]: result

    Out[26]: 

       one  two  thress

    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

    同样的使用方式对与DataFrame也是一样的。

    concat函数的参数如下

    重塑和轴向旋转

    在线性代数中我们有转置的操作。在pandas中我们也可以进行类似的操作

    stack:将数据的列旋转为行

    unstack:将数据的行旋转为列

    In [27]: data=DataFrame(np.arange(6).reshape((2,3)),index=pd.Index(['Ohio','Colo

        ...: rado'],name='state'),columns=pd.Index(['one','two','three'],name='numbe

        ...: r'))

    In [28]: data

    Out[28]: 

    number    one  two  three

    state                    

    Ohio        0    1      2

    Colorado    3    4      5

    In [29]: result=data.stack()

    In [30]: result

    Out[30]: 

    state     number

    Ohio      one       0

              two       1

              three     2

    Colorado  one       3

              two       4

              three     5

    dtype: int64

    In [31]: result.unstack()

    Out[31]: 

    number    one  two  three

    state                    

    Ohio        0    1      2

    Colorado    3    4      5

    由于我们分别建立了行和列的索引,分别是statenumber,因此我们可以指定索引来进行对应的转换

    In [33]: result.unstack('state')

    Out[33]: 

    state   Ohio  Colorado

    number                

    one        0         3

    two        1         4

    three      2         5

    In [34]: result.unstack('number')

    Out[34]: 

    number    one  two  three

    state                    

    Ohio        0    1      2

    Colorado    3    4      5

    如果不是所有的数据都在索引中能找到的话,则unstack操作会引入缺失的数据

    In [35]: s1=Series([0,1,2,3],index=['a','b','c','d'])

    In [38]: s2=Series([4,5,6],index=['c','d','e'])

    In [40]: data=pd.concat([s1,s2],keys=['one','two'])

    In [41]: data

    Out[41]: 

    one  a    0

         b    1

         c    2

         d    3

    two  c    4

         d    5

         e    6

    dtype: int64

    In [43]: data.unstack()

    Out[43]: 

           a    b    c    d    e

    one  0.0  1.0  2.0  3.0  NaN

    two  NaN  NaN  4.0  5.0  6.0

  • 相关阅读:
    如何有效地报告 Bug
    Linux开始结束ping命令
    【转】未能加载文件或程序集“XXX”或它的某一个依赖项。试图加载格式不正确的程序。
    .net session 使用误区
    [转] ADO.NET调用存储过程带输出参数或返回值
    ASP.NET Easyui datagrid增删改+sqlhelper
    C#分割字符串并统计重复出现的次数
    C# 读取TXT文本数据 添加到数据库
    记一次Spring项目打包问题排查
    Wiki系列(三):我的Wiki
  • 原文地址:https://www.cnblogs.com/zhanghongfeng/p/8487120.html
Copyright © 2011-2022 走看看