pandasのconcat関数では、ラベルが付いた軸に沿った配列の連結をおこなう。

今回は多くの例を紹介しながら、concat関数の動作を確認していく。

基本の連結

まずは、インデックスに重複の無い3つのシリーズを連結する例だ。

import pandas as pd

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

pd.concat([s1, s2, s3])
# a    0
# b    1
# c    2
# d    3
# e    4
# f    5
# g    6
# dtype: int64

concat関数の引数にオブジェクトを格納したリストを与えると、与えられたオブジェクト(この場合シリーズ)が連結される。

また、デフォルトでは行方向へ連結されるが、以下のように列方向へ連結することも可能だ。

df = 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

内部結合による連結

先ほどの例ではラベルに重複がなく、結合された結果を見ると外部結合であることが分かった。

内部結合をおこなう場合は、joinオプションにより別途指定する必要がある。

import pandas as pd

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

s4 = pd.concat([s1, s3])
# a    0
# b    1
# f    5
# g    6
# dtype: int64

df_outer = pd.concat([s1, s4], axis=1)
#      0  1
# a  0.0  0
# b  1.0  1
# f  NaN  5
# g  NaN  6

df_inner = pd.concat([s1, s4], axis=1, join='inner')
#    0  1
# a  0  0
# b  1  1

連結する軸を指定する

join_axesオプションを使うことで、連結する軸を任意で指定することも可能だ。

df = pd.concat([s1, s4], axis=1, join_axes=[['a', 'b', 'e']])
#      0    1
# a  0.0  0.0
# b  1.0  1.0
# e  NaN  NaN

連結したオブジェクトに階層型インデックスを持たせる

単純な連結操作では、連結後のオブジェクトの要素が、連結前のどの要素に対応しているかが分からなくなることがある。

そういった場合は、連結後のオブジェクトに階層型インデックスを持たせると良い。

concat関数のkeysオプションを設定すれば、階層型インデックスを持たせることができ、以下のような結果となる。

df_h = pd.concat([s1, s1, s3], keys=['one', 'two', 'three'])
# one    a    0
#        b    1
# two    a    0
#        b    1
# three  f    5
#        g    6
# dtype: int64

axis=1と列方向へ連結する場合は、keysに指定した値が列名として設定される。

df_h = 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

データフレームの結合の場合

シリーズがデータフレームになってもconcat関数の使い方は変わりない。

import pandas as pd
import numpy as np

df1 = pd.DataFrame(np.arange(6).reshape(3, 2),
                  index=['a', 'b', 'c'],
                  columns=['one', 'two'])
#    one  two
# a    0    1
# b    2    3
# c    4    5

df2 = pd.DataFrame(5 + np.arange(4).reshape(2, 2),
                  index=['a', 'c'], 
                  columns=['three', 'four'])
#    three  four
# a      5     6
# c      7     8

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による階層型インデックスを持たせた結合は、以下のようにconcat関数にディクショナリを渡すことでも同様の結果が得られる。

pd.concat({'level1': df1, 'level2': df2}, axis=1)
#   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