美文网首页pythonPython
Python数据分析_Pandas02_数据框的合并和重整

Python数据分析_Pandas02_数据框的合并和重整

作者: ChZ_CC | 来源:发表于2017-02-03 16:13 被阅读3598次
    主要内容:
    • 数据拼接:join、merge、contact、append
    • 数据重整:reshape -- stuck、unstuck
    • 数据透视表:pivot tables

    数据拼接

    1. concat

    参数介绍:

    pd.concat(objs, axis=0, join='outer', join_axes=None, ignore_index=False,
              keys=None, levels=None, names=None, verify_integrity=False,
              copy=True)
    
    axis:要粘在哪个轴上。默认0,粘贴行。
    join:默认outer,合集;inner,交集。
    ignore_index:布尔型,默认False。如果为Ture的话,会重新分配index从0...n-1。
    keys:一个序列,默认None。建立等级索引,作为最外层的level。
    levels:序列sequences构成的list,默认None。
    

    示例:

    In [41]: df1 = pd.DataFrame({'A': ['A0', 'A1', 'A2', 'A3'],
        ...:                     'B': ['B0', 'B1', 'B2', 'B3'],
        ...:                     'C': ['C0', 'C1', 'C2', 'C3'],
        ...:                     'D': ['D0', 'D1', 'D2', 'D3']},
        ...:                     index=[0, 1, 2, 3])
    
    In [42]: df2 = pd.DataFrame({'A': ['A4', 'A5', 'A6', 'A7'],
        ...:                     'B': ['B4', 'B5', 'B6', 'B7'],
        ...:                     'C': ['C4', 'C5', 'C6', 'C7'],
        ...:                     'D': ['D4', 'D5', 'D6', 'D7']},
        ...:                      index=[4, 5, 6, 7])
        ...:
    
    In [43]: df3 = pd.DataFrame({'A': ['A8', 'A9', 'A10', 'A11'],
        ...:                     'B': ['B8', 'B9', 'B10', 'B11'],
        ...:                     'C': ['C8', 'C9', 'C10', 'C11'],
        ...:                     'D': ['D8', 'D9', 'D10', 'D11']},
        ...:                     index=[8, 9, 10, 11])
        ...:
    
    In [44]: frames = [df1, df2, df3]
    
    In [45]: result = pd.concat(frames)
    
    In [46]: result
    Out[46]:
          A    B    C    D
    0    A0   B0   C0   D0
    1    A1   B1   C1   D1
    2    A2   B2   C2   D2
    3    A3   B3   C3   D3
    4    A4   B4   C4   D4
    5    A5   B5   C5   D5
    6    A6   B6   C6   D6
    7    A7   B7   C7   D7
    8    A8   B8   C8   D8
    9    A9   B9   C9   D9
    10  A10  B10  C10  D10
    11  A11  B11  C11  D11
    
    In [47]:  result2 = pd.concat(frames, keys=['x', 'y', 'z'])
    
    In [48]: result2
    Out[48]:
            A    B    C    D
    x 0    A0   B0   C0   D0
      1    A1   B1   C1   D1
      2    A2   B2   C2   D2
      3    A3   B3   C3   D3
    y 4    A4   B4   C4   D4
      5    A5   B5   C5   D5
      6    A6   B6   C6   D6
      7    A7   B7   C7   D7
    z 8    A8   B8   C8   D8
      9    A9   B9   C9   D9
      10  A10  B10  C10  D10
      11  A11  B11  C11  D11
    
    In [51]: result2.index    # result2的shape是(12,4),多重索引,如下:
    Out[51]:
    MultiIndex(levels=[['x', 'y', 'z'], [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]],
               labels=[[0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2], [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]])
    
    In [49]: result2.ix['y']                # .ix 等级索引
    Out[49]:
        A   B   C   D
    4  A4  B4  C4  D4
    5  A5  B5  C5  D5
    6  A6  B6  C6  D6
    7  A7  B7  C7  D7
    

    contact会生成一个copy,比较费内存。如果要用的话,最好把所有要拼接的数据框放一list中,一次concat所有。像这样:

    frames = [ process_your_file(f) for f in files ]
    result = pd.concat(frames)
    

    2. append

    和python中list的append不同,这里的append不改变原来的数据框,返回一个拼接后的copy。

    In [57]: appended = df1.append([df2, df3])
    
    In [58]: appended
    Out[58]:
          A    B    C    D
    0    A0   B0   C0   D0
    1    A1   B1   C1   D1
    2    A2   B2   C2   D2
    3    A3   B3   C3   D3
    4    A4   B4   C4   D4
    5    A5   B5   C5   D5
    6    A6   B6   C6   D6
    7    A7   B7   C7   D7
    8    A8   B8   C8   D8
    9    A9   B9   C9   D9
    10  A10  B10  C10  D10
    11  A11  B11  C11  D11
    
    In [59]: df1
    Out[59]:
        A   B   C   D
    0  A0  B0  C0  D0
    1  A1  B1  C1  D1
    2  A2  B2  C2  D2
    3  A3  B3  C3  D3
    

    添加一行:【注】ignore_index=True

    可以添加Series或list(放着dicts的list)

    In [80]: s2 = pd.Series(['X0', 'X1', 'X2', 'X3'],index=df1.columns)
    In [83]: df1_s2 =  df1.append(s2,ignore_index=True)
    
    In [84]: df1_s2
    Out[84]:
        A   B   C   D
    0  A0  B0  C0  D0
    1  A1  B1  C1  D1
    2  A2  B2  C2  D2
    3  A3  B3  C3  D3
    4  X0  X1  X2  X3
    
    dicts = [{'A': 1, 'B': 2, 'C': 3, 'X': 4},
             {'A': 5, 'B': 6, 'C': 7, 'Y': 8}]
    result = df1.append(dicts, ignore_index=True)
    

    下面的merge和join是针对数据框合并的,一般都是列合并。

    3. merge

    参数介绍:

    pd.merge(left, right, how='inner', on=None, left_on=None, right_on=None,
             left_index=False, right_index=False, sort=True,
             suffixes=('_x', '_y'), copy=True, indicator=False)
             
    left: 一个dataframe对象
    right: 另一个dataframe对象
    how: 可以是'left', 'right', 'outer', 'inner'. 默认为inner。
    on: 列名,两个dataframe都有的列。如果不传参数,
        而且left_index和right_index也等于False,
        则默认把两者交叉/共有的列作为链接键(join keys)。
        可以是一个列名,也可以是包含多个列名的list。
    left_on: 左边dataframe的列会用做keys。可以是列名,
        或者与dataframe长度相同的矩阵array。
    right_on: 右边同上。
    left_index: 如果为Ture,用左侧dataframe的index作为
        连接键。如果是多维索引,level数要跟右边相同才行。
    right_index: 右边同上。
    sort: 对合并后的数据框排序,以连接键。
    suffixes: 一个tuple,包字符串后缀,用来加在重叠的列名后面。
        默认是('_x','_y')。
    copy: 默认Ture,复制数据。
    indicator: 布尔型(True/FALSE),或是字符串。
        如果为True,合并之后会增加一列叫做'_merge'。
        是分类数据,用left_only, right_only, both来标记
        来自左边,右边和两边的数据。
    

    示例:

    In [4]: left = pd.DataFrame({'key': ['K0', 'K1', 'K2', 'K3'],
       ...:                      'A': ['A0', 'A1', 'A2', 'A3'],
       ...:                      'B': ['B0', 'B1', 'B2', 'B3']})
       ...:
    
    In [6]: right = pd.DataFrame({'key': ['K1', 'K2', 'K3', 'K4'],
       ...:                       'C': ['C0', 'C1', 'C2', 'C3'],
       ...:                       'D': ['D0', 'D1', 'D2', 'D3']})
       ...:
    
    #默认inner合并,只保留共同的部分。
    In [7]: pd.merge(left, right, on='key')
    Out[7]:
        A   B key   C   D
    0  A1  B1  K1  C0  D0
    1  A2  B2  K2  C1  D1
    2  A3  B3  K3  C2  D2
    
    #outer方式合并
    In [8]: pd.merge(left, right, how='outer', on='key')
    Out[8]:
         A    B key    C    D
    0   A0   B0  K0  NaN  NaN
    1   A1   B1  K1   C0   D0
    2   A2   B2  K2   C1   D1
    3   A3   B3  K3   C2   D2
    4  NaN  NaN  K4   C3   D3
    
    #indicator,用来标示数据来源。
    In [11]: In [8]: pd.merge(left, right, how='outer', on='key', indicator = 'indicator_colomn')
    Out[11]:
         A    B key    C    D indicator_colomn
    0   A0   B0  K0  NaN  NaN        left_only
    1   A1   B1  K1   C0   D0             both
    2   A2   B2  K2   C1   D1             both
    3   A3   B3  K3   C2   D2             both
    4  NaN  NaN  K4   C3   D3       right_only
    

    4. Join

    另一个便捷的合并数据框的方法。

    参数介绍:

    DataFrame.join(other, on=None, how='left', lsuffix='', rsuffix='', sort=False)
    
    other:一个DataFrame、Series(要有命名),或者DataFrame组成的list。
    on:列名,包含列名的list或tuple,或矩阵样子的列
        (如果是多列,必须有MultiIndex)。
        跟上面的几种方法一样,用来指明依据哪一列进行合并。
        如果没有赋值,则依据两个数据框的index合并。
    how:合并方式, {‘left’, ‘right’, ‘outer’, ‘inner’},
        默认 ‘left’调用函数的数据框。
    lsuffix:字符串。用于左侧数据框的重复列。
        把重复列重新命名,原来的列名+字符串。
        【如果有重复列,必须添加这个参数。】
    rsuffix:同上。右侧。
    sort:布尔型,默认False。如果为True,将链接键(on的那列)按字母排序。
    

    示例:

    In [3]: left = pd.DataFrame({'A': ['A0', 'A1', 'A2'],
       ...:                      'B': ['B0', 'B1', 'B2'],
       ...:                      'D': ['D3', 'D4', 'D5']},
       ...:                      index=['K0', 'K1', 'K2'])
       ...:
       ...: right = pd.DataFrame({'C': ['C0', 'C2', 'C3'],
       ...:                       'D': ['D0', 'D2', 'D3']},
       ...:                       index=['K0', 'K2', 'K3'])
       ...:
       
    In [5]: left.join(right, lsuffix='_left', rsuffix='_right')
    Out[5]:
         A   B D_left    C D_right
    K0  A0  B0     D3   C0      D0
    K1  A1  B1     D4  NaN     NaN
    K2  A2  B2     D5   C2      D2
    
    In [8]: left.join(right, on='D', how='outer', lsuffix='_left', rsuffix='_right')
    Out[8]:
         D    A    B D_left    C D_right
    K0  D3   A0   B0     D3  NaN     NaN
    K1  D4   A1   B1     D4  NaN     NaN
    K2  D5   A2   B2     D5  NaN     NaN
    K2  K0  NaN  NaN    NaN   C0      D0
    K2  K2  NaN  NaN    NaN   C2      D2
    K2  K3  NaN  NaN    NaN   C3      D3
    
    #对比没有'on'的情况。对于上面第8行输出有点儿懵逼。
    In [9]: left.join(right, how='outer', lsuffix='_left', rsuffix='_right')
    Out[9]:
          A    B D_left    C D_right
    K0   A0   B0     D3   C0      D0
    K1   A1   B1     D4  NaN     NaN
    K2   A2   B2     D5   C2      D2
    K3  NaN  NaN    NaN   C3      D3
    
    # 使用默认索引的时候:
    In [10]: left = pd.DataFrame({'A': ['A0', 'A1', 'A2'],
        ...:                      'B': ['B0', 'B1', 'B2'],
        ...:                      'D': ['D3', 'D4', 'D5']})
        ...: right = pd.DataFrame({'C': ['C0', 'C2', 'C3'],
        ...:                       'D': ['D0', 'D2', 'D3']})
        ...:
    
    In [11]: left.join(right, lsuffix='_left', rsuffix='_right')
    Out[11]:
        A   B D_left   C D_right
    0  A0  B0     D3  C0      D0
    1  A1  B1     D4  C2      D2
    2  A2  B2     D5  C3      D3
    
    

    合并数据框这些方法大同小异,选一个能满足需要就行啦。


    数据重整

    pivot

    用于生成一个数据透视表。

    参数介绍:

    DataFrame.pivot(index=None, columns=None, values=None)[source]
    
    index:字符串或对象,可选。列名,用来当新数据框index的列,可以是多个列名的list。
    columns:字符串或对象。列名,当做新数据框的列。
    values:字符串或对象,可选。列名,生成新数据框的值。
        如果没有指定,则使用余下的所有列,会生成等级索引列。
    

    示例:

    In [16]: df = pd.DataFrame({'foo': ['one','one','one','two','two','two'],
        ...:                    'bar': ['A', 'B', 'C', 'A', 'B', 'C'],
        ...:                    'baz': [1, 2, 3, 4, 5, 6]})
    
    In [20]: df
    Out[20]:
      bar  baz  foo
    0   A    1  one
    1   B    2  one
    2   C    3  one
    3   A    4  two
    4   B    5  two
    5   C    6  two
    
    In [21]: df.pivot(index='foo', columns='bar', values='baz')
        ...:
    Out[21]:
    bar  A  B  C
    foo
    one  1  2  3
    two  4  5  6
    
    # 有多列数值的情况
    In [22]: df['baz_2'] = df['baz']*2
    
    In [23]: df.pivot(index='foo', columns='bar')
    Out[23]:
        baz       baz_2
    bar   A  B  C     A   B   C
    foo
    one   1  2  3     2   4   6
    two   4  5  6     8  10  12
    
    # 另一种选择数值value的方法
    In [24]: df.pivot(index='foo', columns='bar')['baz_2']
    Out[24]:
    bar  A   B   C
    foo
    one  2   4   6
    two  8  10  12
    

    升级版pivot:pandas.DataFrame.pivot_table。有更多的参数。个人感觉比较鸡肋,复杂的分类汇总有其他的函数可用。

    stack 和 unstack

    另一种重整数据的方法。stack和unstack是互逆方式。参数很简单。直接贴个例子好了

    In [41]: df2 = df.pivot(index='foo', columns='bar')['baz_2']
        ...: df2
        ...:
    Out[41]:
    bar  A   B   C
    foo
    one  2   4   6
    two  8  10  12
    
    In [42]: stacked = df2.stack()
    
    In [43]: stacked
    Out[43]:
    foo  bar
    one  A       2
         B       4
         C       6
    two  A       8
         B      10
         C      12
    dtype: int64
    
    In [44]: stacked.unstack()
    Out[44]:
    bar  A   B   C
    foo
    one  2   4   6
    two  8  10  12
    

    相关文章

      网友评论

        本文标题:Python数据分析_Pandas02_数据框的合并和重整

        本文链接:https://www.haomeiwen.com/subject/zuhnbttx.html