note.nkmk.me

pandas.DataFrame, Seriesを連結するconcat

Date: 2015-07-29 / Modified: 2018-04-26 / tags: Python, pandas

複数のpandas.DataFrame, pandas.Seriesを連結(結合)するpandas.concat()関数の使い方について説明する。

新たに行や列を追加するにはconcat()よりもその他の方法のほうが簡単な場合がある。詳細は以下の記事を参照。

今回の説明では以下のオブジェクトを生成して使う。

import pandas as pd

df1 = pd.DataFrame({'A': ['A1', 'A2', 'A3'],
                    'B': ['B1', 'B2', 'B3'],
                    'C': ['C1', 'C2', 'C3']},
                   index=['ONE', 'TWO', 'THREE'])
print(df1)
#         A   B   C
# ONE    A1  B1  C1
# TWO    A2  B2  C2
# THREE  A3  B3  C3

df2 = pd.DataFrame({'C': ['C2', 'C3', 'C4'],
                    'D': ['D2', 'D3', 'D4']},
                   index=['TWO', 'THREE', 'FOUR'])
print(df2)
#         C   D
# TWO    C2  D2
# THREE  C3  D3
# FOUR   C4  D4

s1 = pd.Series(['X1', 'X2', 'X3'], index=['ONE', 'TWO', 'THREE'], name='X')
print(s1)
# ONE      X1
# TWO      X2
# THREE    X3
# Name: X, dtype: object

s2 = pd.Series(['Y2', 'Y3', 'Y4'], index=['TWO', 'THREE', 'FOUR'], name='Y')
print(s2)
# TWO      Y2
# THREE    Y3
# FOUR     Y4
# Name: Y, dtype: object

説明する内容は以下の通り。

  • pandas.concat()の基本的な使い方
    • 連結するオブジェクトを指定: 引数objs
    • 連結方向(縦・横)の指定: 引数axis
    • 連結方法(外部結合・内部結合)の指定: 引数join
  • pandas.DataFrame同士の連結
  • pandas.Series同士の連結
  • pandas.DataFramepandas.Seriesの連結

日付や名前などの共通のデータ列を持っている複数のpandas.DataFrameをその列の値に従って結合するにはpandas.merge()関数またはpandas.DataFramemerge()メソッドを使う。以下の記事を参照。

スポンサーリンク

pandas.concat()の基本的な使い方

連結するオブジェクトを指定: 引数objs

第一引数objsに連結するpandas.DataFrame, pandas.Seriesをリストやタプルで指定する。

df_concat = pd.concat([df1, df2])
print(df_concat)
#          A    B   C    D
# ONE     A1   B1  C1  NaN
# TWO     A2   B2  C2  NaN
# THREE   A3   B3  C3  NaN
# TWO    NaN  NaN  C2   D2
# THREE  NaN  NaN  C3   D3
# FOUR   NaN  NaN  C4   D4

連結するオブジェクトの個数は2個に限らず3個以上でもOK。

df_concat_multi = pd.concat([df1, df2, df1])
print(df_concat_multi)
#          A    B   C    D
# ONE     A1   B1  C1  NaN
# TWO     A2   B2  C2  NaN
# THREE   A3   B3  C3  NaN
# TWO    NaN  NaN  C2   D2
# THREE  NaN  NaN  C3   D3
# FOUR   NaN  NaN  C4   D4
# ONE     A1   B1  C1  NaN
# TWO     A2   B2  C2  NaN
# THREE   A3   B3  C3  NaN

新たなオブジェクトが生成され、元のオブジェクトは変更されない。

連結方向(縦・横)の指定: 引数axis

縦方向、横方向いずれの方向に連結するかは引数axisで指定する。

axis=0とすると縦方向に連結される。これがデフォルトなので省略しても同じ。

df_v = pd.concat([df1, df2], axis=0)
print(df_v)
#          A    B   C    D
# ONE     A1   B1  C1  NaN
# TWO     A2   B2  C2  NaN
# THREE   A3   B3  C3  NaN
# TWO    NaN  NaN  C2   D2
# THREE  NaN  NaN  C3   D3
# FOUR   NaN  NaN  C4   D4

axis=1とすると横方向に連結される。

df_h = pd.concat([df1, df2], axis=1)
print(df_h)
#          A    B    C    C    D
# FOUR   NaN  NaN  NaN   C4   D4
# ONE     A1   B1   C1  NaN  NaN
# THREE   A3   B3   C3   C3   D3
# TWO     A2   B2   C2   C2   D2

連結方法(外部結合・内部結合)の指定: 引数join

連結した結果、列名(または行名)の和集合とするか、共通部分のみを残すか引数joinで指定する。

join='outer'は外部結合。列名(または行名)は和集合となり、すべての列(または行)が残る。これがデフォルトなので省略しても同じ。この場合、元のオブジェクトに存在しない列(または行)の要素は欠損値NaNとなる。

join='inner'は内部結合。共通の列名(または行名)の列(または行)のみが残る。

df_v_out = pd.concat([df1, df2], join='outer')
print(df_v_out)
#          A    B   C    D
# ONE     A1   B1  C1  NaN
# TWO     A2   B2  C2  NaN
# THREE   A3   B3  C3  NaN
# TWO    NaN  NaN  C2   D2
# THREE  NaN  NaN  C3   D3
# FOUR   NaN  NaN  C4   D4

df_v_in = pd.concat([df1, df2], join='inner')
print(df_v_in)
#         C
# ONE    C1
# TWO    C2
# THREE  C3
# TWO    C2
# THREE  C3
# FOUR   C4

横方向でも同じ。

df_h_out = pd.concat([df1, df2], axis=1, join='outer')
print(df_h_out)
#          A    B    C    C    D
# FOUR   NaN  NaN  NaN   C4   D4
# ONE     A1   B1   C1  NaN  NaN
# THREE   A3   B3   C3   C3   D3
# TWO     A2   B2   C2   C2   D2

df_h_in = pd.concat([df1, df2], axis=1, join='inner')
print(df_h_in)
#         A   B   C   C   D
# TWO    A2  B2  C2  C2  D2
# THREE  A3  B3  C3  C3  D3

pandas.DataFrame同士の連結

これまでの例のようにpandas.DataFrame同士を連結すると、pandas.DataFrame型のオブジェクトが返る。

df_concat = pd.concat([df1, df2])
print(df_concat)
#          A    B   C    D
# ONE     A1   B1  C1  NaN
# TWO     A2   B2  C2  NaN
# THREE   A3   B3  C3  NaN
# TWO    NaN  NaN  C2   D2
# THREE  NaN  NaN  C3   D3
# FOUR   NaN  NaN  C4   D4

print(type(df_concat))
# <class 'pandas.core.frame.DataFrame'>

pandas.Series同士の連結

pandas.Series同士の連結の場合、縦方向の連結(axis=0、デフォルト)ではpandas.Series型のオブジェクトが返る。

s_v = pd.concat([s1, s2])
print(s_v)
# ONE      X1
# TWO      X2
# THREE    X3
# TWO      Y2
# THREE    Y3
# FOUR     Y4
# dtype: object

print(type(s_v))
# <class 'pandas.core.series.Series'>

横方向の連結(axis=1)ではpandas.DataFrame型のオブジェクトが返る。

s_h = pd.concat([s1, s2], axis=1)
print(s_h)
#          X    Y
# FOUR   NaN   Y4
# ONE     X1  NaN
# THREE   X3   Y3
# TWO     X2   Y2

print(type(s_h))
# <class 'pandas.core.frame.DataFrame'>

引数joinも使える。

s_h_in = pd.concat([s1, s2], axis=1, join='inner')
print(s_h_in)
#         X   Y
# TWO    X2  Y2
# THREE  X3  Y3

pandas.DataFrameとpandas.Seriesの連結

pandas.DataFramepandas.Seriesの連結の場合、横方向の連結(axis=1)ではpandas.Seriesが新たな列として追加される。pandas.Seriesnameが列名となる。

df_s_h = pd.concat([df1, s2], axis=1)
print(df_s_h)
#          A    B    C    Y
# FOUR   NaN  NaN  NaN   Y4
# ONE     A1   B1   C1  NaN
# THREE   A3   B3   C3   Y3
# TWO     A2   B2   C2   Y2

引数joinも使える。

df_s_h_in = pd.concat([df1, s2], axis=1, join='inner')
print(df_s_h_in)
#         A   B   C   Y
# TWO    A2  B2  C2  Y2
# THREE  A3  B3  C3  Y3

縦方向の連結(axis=0、デフォルト)では以下のような結果となる。

df_s_v = pd.concat([df1, s2])
print(df_s_v)
#          A    B    C    0
# ONE     A1   B1   C1  NaN
# TWO     A2   B2   C2  NaN
# THREE   A3   B3   C3  NaN
# TWO    NaN  NaN  NaN   Y2
# THREE  NaN  NaN  NaN   Y3
# FOUR   NaN  NaN  NaN   Y4

行を追加する場合は、.locで新たな行名を指定して値を代入する、append()メソッドを使うなどの方法がある。

df1.loc['FOUR'] = ['A4', 'B4', 'C4']
print(df1)
#         A   B   C
# ONE    A1  B1  C1
# TWO    A2  B2  C2
# THREE  A3  B3  C3
# FOUR   A4  B4  C4

s = pd.Series(['A5', 'B5', 'C5'], index=df1.columns, name='FIVE')
print(s)
# A    A5
# B    B5
# C    C5
# Name: FIVE, dtype: object

df_append = df1.append(s)
print(df_append)
#         A   B   C
# ONE    A1  B1  C1
# TWO    A2  B2  C2
# THREE  A3  B3  C3
# FOUR   A4  B4  C4
# FIVE   A5  B5  C5

append()メソッドの場合、pandas.DataFrameの列名columnspandas.Seriesのラベルindexが一致している必要がある。詳細は以下の記事を参照。

スポンサーリンク
シェア
このエントリーをはてなブックマークに追加

関連カテゴリー

関連記事