• 利用Python进行数据分析——数据规整化:清理、转换、合并、重塑(七)(1)


    数据分析和建模方面的大量编程工作都是用在数据准备上的:载入、清理、转换以及重塑。有时候,存放在文件或数据库中的数据并不能满足你的数据处理应用的要求。很多人都选择使用通用编程语言(如Python、Perl、R或Java)或UNIX文本处理工具(如sed或awk)对数据格式进行专门处理。幸运的是,pandas和Python标准库提供了一组高级的、灵活的、高效的核心函数和算法,它们使你可以轻松地将数据规整化为正确的形式。

    1、合并数据集

    pandas对象中的数据能够通过一些内置的方式进行合并:

    • pandas.merge可依据一个或多个键将不同DataFrame中的行连接起来。SQL或其它关系型数据库的用户对此应该会比較熟悉,由于它实现的就是数据库的连接操作。
    • pandas.concat能够沿着一条轴将多个对象堆叠到一起。
    • 实例方法combine_first能够将反复数据编接在一起,用一个对象中的值填充还有一个对象中的缺失值。


    2、数据库风格的DataFrame合并

    数据集的合并(merge)或连接(join)运算是通过一个或多个键将行链接起来的。这些运算是关系型数据库的核心。pandas的merge函数是对数据应用这些算法的主要切入点。

    In [4]: import pandas as pd
    
    In [5]: import numpy as np
    
    In [6]: df1 = pd.DataFrame({'key': ['b', 'b', 'a', 'c', 'a', 'a', 'b'],
       ...:                     'data1': range(7)})
    
    In [7]: df2 = pd.DataFrame({'key': ['a', 'b', 'd'],
       ...:                     'data2': range(3)})
    
    In [8]: df1
    Out[8]: 
       data1 key
    0      0   b
    1      1   b
    2      2   a
    3      3   c
    4      4   a
    5      5   a
    6      6   b
    
    [7 rows x 2 columns]
    
    In [9]: df2
    Out[9]: 
       data2 key
    0      0   a
    1      1   b
    2      2   d
    
    [3 rows x 2 columns]
    
    这是一种多对一的合并。df1中的数据有多个被标记为a和b的行,而df2中key列的每一个值则仅相应一行。对这些对象调用merge就可以得到:

    In [10]: pd.merge(df1, df2)
    Out[10]: 
       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
    
    [6 rows x 3 columns]
    注意,我并没有指明要用哪个列进行连接。假设没有指定,merge就会将重叠列的列名当做键。只是,最好显示指定一下:

    In [11]: pd.merge(df1, df2, on='key')
    Out[11]: 
       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
    
    [6 rows x 3 columns]
    
    假设两个对象的列名不同,也能够分别进行指定:

    In [12]: df3 = pd.DataFrame({'lkey': ['b', 'b', 'a', 'c', 'a', 'a', 'b'],
       ....:                     'data1': range(7)})
    
    In [13]: df4 = pd.DataFrame({'rkey': ['a', 'b', 'd'],
       ....:                     'data2': range(3)})
    
    In [14]: pd.merge(df)
    df1  df2  df3  df4  
    
    In [14]: pd.merge(df3, df4, left_on='lkey', right_on='rkey')
    Out[14]: 
       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
    
    [6 rows x 4 columns]
    
    可能你已经主要到了,结果里面c和d以及与之相关的数据消失了。默认情况下,merge做的是“inner”连接;结果中的键是交集。其它方式还有“left”、“right”以及“outer”。外连接求取的是键的交集,组合了左连接和右连接的效果:

    In [16]: pd.merge(df1, df2, how='outer')
    Out[16]: 
       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
    6      3   c    NaN
    7    NaN   d      2
    
    [8 rows x 3 columns]
    
    多对多的合并操作很easy,无需额外的工作。例如以下所看到的:

    In [17]: df1 = pd.DataFrame({'key': ['b', 'b', 'a', 'c', 'a', 'b'],
       ....:                     'data1': range(6)})
    
    In [18]: df2 = pd.DataFrame({'key': ['a', 'b', 'a', 'b', 'd'],
       ....:                     'data2': range(5)})
    
    In [19]: df1
    Out[19]: 
       data1 key
    0      0   b
    1      1   b
    2      2   a
    3      3   c
    4      4   a
    5      5   b
    
    [6 rows x 2 columns]
    
    In [20]: df2
    Out[20]: 
       data2 key
    0      0   a
    1      1   b
    2      2   a
    3      3   b
    4      4   d
    
    [5 rows x 2 columns]
    
    In [21]: pd.merge(df1, df2, on='key', how='left')
    Out[21]: 
        data1 key  data2
    0       0   b      1
    1       0   b      3
    2       1   b      1
    3       1   b      3
    4       5   b      1
    5       5   b      3
    6       2   a      0
    7       2   a      2
    8       4   a      0
    9       4   a      2
    10      3   c    NaN
    
    [11 rows x 3 columns]
    
    多对多连接产生的是行的笛卡尔积。因为左边的DataFrame有3个“b”行,右边的有2个,所以终于结果中就有6个“b”行。连接方式仅仅影响出如今结果中的键:

    In [23]: pd.merge(df1, df2, on='key', how='inner')
    Out[23]: 
       data1 key  data2
    0      0   b      1
    1      0   b      3
    2      1   b      1
    3      1   b      3
    4      5   b      1
    5      5   b      3
    6      2   a      0
    7      2   a      2
    8      4   a      0
    9      4   a      2
    
    [10 rows x 3 columns]
    
    要依据多个键进行合并,传入一个由列名组成的列表就可以:

    In [24]: left = pd.DataFrame({'key1': ['foo', 'foo', 'bar'],
       ....:                      'key2': ['one', 'two', 'one'],
       ....:                      'lval': [1, 2, 3]})
    
    In [25]: right = pd.DataFrame({'key1': ['foo', 'foo', 'bar', 'bar'],
       ....:                       'key2': ['one', 'one', 'one', 'two'],
       ....:                       'rval': [4, 5, 6, 7]})
    
    In [26]: pd.merge(left, right, on=['key1', 'key2'], how='outer')
    Out[26]: 
      key1 key2  lval  rval
    0  foo  one     1     4
    1  foo  one     1     5
    2  foo  two     2   NaN
    3  bar  one     3     6
    4  bar  two   NaN     7
    
    [5 rows x 4 columns]
    
    结果中会出现哪些键组合取决于所选的合并方式,你能够这样来理解:多个键形成一系列元组,并将其当做单个连接键(当然,实际上并非这么回事)。

    警告:

    在进行列-列连接时,DataFrame对象中的索引会被丢弃。

    对于合并运算须要须要考虑的最后一个问题是对反复列名的处理。尽管你能够手工处理列名重叠的问题,但merge有一个更有用的suffixes选项,用于指定附加到左右两个DataFrame对象的重叠列名上的字符串:

    In [27]: pd.merge(left, right, on='key1')
    Out[27]: 
      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
    
    [6 rows x 5 columns]
    
    In [28]: pd.merge(left, right, on='key1', suffixes=('_left', '_right'))
    Out[28]: 
      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
    
    [6 rows x 5 columns]
    

  • 相关阅读:
    [LeetCode]Interleaving String关于遍历和动态规划
    [LeetCode]Power
    [LeetCode]Two Sum
    [LeetCode]wildcard matching通配符实现之贪心法
    [LeetCode]wildcard matching通配符实现之动态规划
    [LeetCode]wildcard matching通配符实现之递归
    回文分割
    iOS开发之应用内检测手机锁屏,解锁状态
    iOS 拨打电话
    iOS 中文转拼音
  • 原文地址:https://www.cnblogs.com/lcchuguo/p/4068779.html
Copyright © 2020-2023  润新知