pandas对象中的数据可以通过一些内置的方式进行合并。

pandas.merge可以根据一个或多个键将不同DataFrame中的行连接起来。

df1 = DataFrame({'key': ['b', 'b', 'a', 'c', 'a', 'a', 'b'],
                 'data1': range(7)})
df2 = DataFrame({'key': ['a', 'b', 'd'],
                 'data2': range(3)})
pd.merge(df1, df2)

如果没有指定,merge会使用重叠列的列名作为键,但最好是显式的指定一下

pd.merge(df1, df2, on='key')

如果两个对象的列名不同,可以分别指定

df3 = DataFrame({'lkey': ['b', 'b', 'a', 'c', 'a', 'a', 'b'],
                 'data1': range(7)})
df4 = DataFrame({'rkey': ['a', 'b', 'd'],
                 'data2': range(3)})
pd.merge(df3, df4, left_on='lkey', right_on='rkey')

    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

可以发现,结果里面c和d以及相关的数据消失了。默认情况下,merge使用的是inner连接。

除此之外,还有left、right、outer。其中outer求取的是键的并集。

pd.merge(df1, df2, how='outer')

    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

如果要根据多个键进行合并,需要传入一个由列名组成的列表

left = DataFrame({'key1': ['foo', 'foo', 'bar'],
                  'key2': ['one', 'two', 'one'],
                  'lval': [1, 2, 3]})
right = DataFrame({'key1': ['foo', 'foo', 'bar', 'bar'],
                   'key2': ['one', 'one', 'one', 'two'],
                   'rval': [4, 5, 6, 7]})
pd.merge(left, right, on=['key1', 'key2'], how='outer')

对于合并运算需要考虑的问题是对重复列名的处理,merge的suffixes选项,用于指定附加到左右两个DataFrame对象的重叠列名上的字符串

pd.merge(left, right, on='key1', suffixes=('_left', '_right'))

索引上的合并

有时,DataFrame中的连接键位于索引中

left1 = DataFrame({'key': ['a', 'b', 'a', 'a', 'b', 'c'],
                  'value': range(6)})
left1


      key    value
0    a    0
1    b    1
2    a    2
3    a    3
4    b    4
5    c    5
right1 = DataFrame({'group_val': [3.5, 7]}, index=['a', 'b'])
right1


     group_val
a    3.5
b    7.0

合并键为索引

pd.merge(left1, right1, left_on='key', right_index=True)

        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

由于默认的merge方法是求取连接键的交集,因此可以通过外连接的方式获得它们的并集

pd.merge(left1, right1, left_on='key', right_index=True, how='outer')

    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

层次化索引合并

对于层次化索引,事情变得有些复杂

lefth = DataFrame({'key1': ['Ohio', 'Ohio', 'Ohio', 'Nevada', 'Nevada'],
                   'key2': [2000, 2001, 2002, 2001, 2002],
                   'data': np.arange(5.)})
lefth


       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
righth = DataFrame(np.arange(12).reshape((6, 2)),
                   index=[['Nevada', 'Nevada', 'Ohio', 'Ohio', 'Ohio', 'Ohio'],
                          [2001, 2000, 2000, 2000, 2001, 2002]],
                   columns=['event1', 'event2'])
righth


               event1    event2
Nevada    2001    0    1
        2000    2    3
Ohio    2000    4    5
        2000    6    7
        2001    8    9
        2002    10    11

必须以列表的形式指明用作合并键的多个列

pd.merge(lefth, righth, left_on=['key1', 'key2'], right_index=True)

    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

合并的并集

pd.merge(lefth, righth, left_on=['key1', 'key2'],
         right_index=True, how='outer')

同时使用合并双方的索引

left2 = DataFrame([[1., 2.], [3., 4.], [5., 6.]], index=['a', 'c', 'e'],
                 columns=['Ohio', 'Nevada'])
left2


       Ohio    Nevada
a    1.0    2.0
c    3.0    4.0
e    5.0    6.0
right2 = DataFrame([[7., 8.], [9., 10.], [11., 12.], [13, 14]],
                   index=['b', 'c', 'd', 'e'], columns=['Missouri', 'Alabama'])
right2

    Missouri    Alabama
b    7.0    8.0
c    9.0    10.0
d    11.0    12.0
e    13.0    14.0

双方都使用索引合并

pd.merge(left2, right2, how='outer', left_index=True, right_index=True)

join实例方法

DataFrame的join实例方法能够更方便的实现按索引合并。

left2.join(right2, how='outer')

DataFrame的join方法是在连接键上做左连接

left1.join(right1, on='key')

对于简单的索引合并,join可以传入一组DataFrame

another = DataFrame([[7., 8.], [9., 10.], [11., 12.], [16., 17.]],
                    index=['a', 'c', 'e', 'f'], columns=['New York', 'Oregon'])
left2.join([right2, another])
left2.join([right2, another], how='outer')

轴向连接

NumPy有一个用于合并原始NumPy数组的concatenate函数

arr = np.arange(12).reshape((3, 4))
np.concatenate([arr, arr], axis=1)

Series的concat操作

假设有3个没有重叠索引的Series

s1 = Series([0, 1], index=['a', 'b'])
s2 = Series([2, 3, 4], index=['c', 'd', 'e'])
s3 = Series([5, 6], index=['f', 'g'])

将值和索引粘合在一起

pd.concat([s1, s2, s3])

默认,concat在axis=0上工作,并最终产生一个新的Series。如果传入axis=1,则结果变为一个DataFrame

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


        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

获取连接的交集

s4 = pd.concat([s1 * 5, s3])
pd.concat([s1, s4], axis=1, join='inner')

通过join_axes指定在其他轴上使用的索引

pd.concat([s1, s4], axis=1, join_axes=[['a', 'c', 'b', 'e']])

如果想在连接轴上创建一个层次化索引,可以使用keys参数

result = pd.concat([s1, s1, s3], keys=['one', 'two', 'three'])
result

one    a    0
       b    1
two    a    0
       b    1
three  f    5
       g    6
dtype: int64

通过unstack升维

result.unstack()


        a    b    f    g
one    0.0    1.0    NaN    NaN
two    0.0    1.0    NaN    NaN
three    NaN    NaN    5.0    6.0

沿axis=1对Series进行合并,则keys成为DataFrame的列头

pd.concat([s1, s2, s3], axis=1, keys=['one', 'two', 'three'])

    one    two    three
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操作

df1 = DataFrame(np.arange(6).reshape(3, 2), index=['a', 'b', 'c'],
                columns=['one', 'two'])
df2 = DataFrame(5 + np.arange(4).reshape(2, 2), index=['a', 'c'],
                columns=['three', 'four'])
pd.concat([df1, df2], axis=1, keys=['level1', 'level2'])

    level1             level2
      one    two    three    four
a    0    1    5.0    6.0
b    2    3    NaN    NaN
c    4    5    7.0    8.0

如果传入的不是列表是字典,则字典的键被当做keys选项的值

pd.concat({'level1': df1, 'level2': df2}, axis=1)

管理层次化创建方式的参数

pd.concat([df1, df2], axis=1, keys=['level1', 'level2'],
          names=['upper', 'lower'])

忽略与数据分析无关的行索引

df1 = DataFrame(np.random.randn(3, 4), columns=['a', 'b', 'c', 'd'])
df2 = DataFrame(np.random.randn(2, 3), columns=['b', 'd', 'a'])
pd.concat([df1, df2], ignore_index=True)

合并重叠数据

假设有索引全部或部分重叠的两个数据集

a = Series([np.nan, 2.5, np.nan, 3.5, 4.5, np.nan],
           index=['f', 'e', 'd', 'c', 'b', 'a'])
a

f    NaN
e    2.5
d    NaN
c    3.5
b    4.5
a    NaN
dtype: float64
b = Series(np.arange(len(a), dtype=np.float64),
           index=['f', 'e', 'd', 'c', 'b', 'a'])
b[-1] = np.nan
b

f    0.0
e    1.0
d    2.0
c    3.0
b    4.0
a    NaN
dtype: float64

NumPy的where函数表达一种矢量化的if-else

np.where(pd.isnull(a), b, a)

array([ 0. ,  2.5,  2. ,  3.5,  4.5,  nan])

Series的combine_first方法实现一样的功能,而且会进行数据对齐

b[:-2].combine_first(a[2:])

a    NaN
b    4.5
c    3.0
d    2.0
e    1.0
f    0.0
dtype: float64

对于DataFrame,combine_first也会在列上做同样的事情,可以认为是用参数对象中的数据为调用者对象的确缺失数据“打补丁”

df1 = DataFrame({'a': [1., np.nan, 5., np.nan],
                 'b': [np.nan, 2., np.nan, 6.],
                 'c': range(2, 18, 4)})
df2 = DataFrame({'a': [5., 4., np.nan, 3., 7.],
                 'b': [np.nan, 3., 4., 6., 8.]})
df1.combine_first(df2)

results matching ""

    No results matching ""