pandas.concat()

当サイトではアフィリエイトプログラムを利用して商品を紹介しています。

【pandas】データセットの連結

pandas.concat() は DataFrame や Series の連結に用いられる関数です。
最初に重複ラベルのない Series 同士を連結してみます。

# PANDAS_CONCAT

# In[1]

import numpy as np
import pandas as pd

# Seriesオブジェクトを作成
s1 = pd.Series(["E01", "E02"], index=list("ab"))
s2 = pd.Series(["E03", "E04"], index=list("cd"))

# pandas.concat()でs1とs2を列方向に連結する
s3 = pd.concat([s1, s2])

print(s3)
# a    E01
# b    E02
# c    E03
# d    E04
# dtype: object

次はラベルが完全一致する Series 同士の連結を試してみます。

# In[2]

# Seriesオブジェクトを作成
s4 = pd.Series(["E1", "E2"], index=list("ab"))
s5 = pd.Series(["E3", "E4"], index=list("ab"))

# pandas.concat()でs4とs5を連結
s6 = pd.concat([s4, s5])

print(s6)
# a    E1
# b    E2
# a    E3
# b    E4
# dtype: object

このように、Series は重複ラベルを許容します。
重複ラベルにアクセスすると、対応するすべての要素が返ります。

# In[3]

# 重複ラベルにアクセス
print(s6["a"])
# a    E1
# a    E3
# dtype: object

しかし、データ分析の実践においては重複ラベルはトラブルのもとなので、なるべく避けたほうがよいでしょう。ignore_index を True に設定すると、古いラベルを破棄して新しいラベルを割り当てます。

# In[4]

# pandas.concat()でs4とs5を連結して新しいラベルを作成
s7 = pd.concat([s4, s5], ignore_index=True)

print(s7)
# 0    E1
# 1    E2
# 2    E3
# 3    E4
# dtype: object

自分でラベルを設定したい場合は、index 属性にアクセスして書き換えます。

# In[5]

# インデクス変更
s6.index = ["a", "b", "c", "d"]

print(s6)
# a    E1
# b    E2
# c    E3
# d    E4
# dtype: object

次は pandas.concat() を使って、ラベルが重複する DataFrame 同士を連結してみます。デフォルトでは列方向 (縦方向) に連結されます。

# In[6]

df1 = pd.DataFrame([["E01", "E02"],
                    ["E03", "E04"]],
                   index = [1, 2], columns=list("ab"))

df2 = pd.DataFrame([["E05", "E06"],
                    ["E07", "E08"]],
                   index = [3, 4], columns=list("ab"))

# pandas.concat()でdf1とdf2を列方向に連結する
df3 = pd.concat([df1, df2])

print(df3)
#      a    b
# 1  E01  E02
# 2  E03  E04
# 3  E05  E06
# 4  E07  E08

行方向 (横方向) につなぐ場合は axis キーワードに 1 を渡します。

# In[7]

# concat()関数でdf1とdf2を行方向に連結する
df4 = pd.concat([df1, df2], axis=1)

print(df4)
#      a    b    a    b
# 1  E01  E02  NaN  NaN
# 2  E03  E04  NaN  NaN
# 3  NaN  NaN  E05  E06
# 4  NaN  NaN  E07  E08

対応するデータがない部分 (欠損値) は自動的に NaN で埋められています。
 
次は列ラベルの一部が重複する DataFrame を連結してみます。

# In[8]

# DataFrameを作成
df5 = pd.DataFrame([["E01", "E02", "E03"],
                    ["E04", "E05", "E06"]],
                   index = [1, 2],
                   columns = list("ABC"))

df6 = pd.DataFrame([["E07", "E08", "E09"],
                    ["E10", "E11", "E12"]],
                   index = [3, 4],
                   columns = list("BCD"))

# df5とdf6の和集合
df7 = pd.concat([df5, df6], sort=True)

print(df7)
#      A    B    C    D
# 1  E01  E02  E03  NaN
# 2  E04  E05  E06  NaN
# 3  NaN  E07  E08  E09
# 4  NaN  E10  E11  E12

このように、pandas.concat() による連結はデフォルトで和集合をとるように設定されています (join=”outer”)。すなわち、ラベルはすべて用いられ、該当する要素がない場合は欠損値として NaN が当てられます。
 
join=”inner” に設定すると積集合をとります (共通するラベルを抽出します)。

# In[9]

# df5とdf6の積集合
df8 = pd.concat([df5, df6], join="inner", sort=True)

print(df8)
#     B    C
# 1  E02  E03
# 2  E05  E06
# 3  E07  E08
# 4  E10  E11

 

コメント

  1. HNaito より:

    下記は誤植と思われますので、ご確認ください。
    CONCAT_01 In[2] プログラムの上の文で、行方向 ( 縦方向 ) → 列方向 ( 縦方向 )
    CONCAT_01 In[2] プログラムのコメントで、行方向に連結 → 列方向に連結
    CONCAT_01 In[3] プログラムの上の文で、列方向 ( 横方向 ) → 行方向 ( 横方向 )
    CONCAT_01 In[3] プログラムのコメントで、列方向に連結 → 行方向に連結

    • あとりえこばと より:

      この記事を書いた頃は「行が増える方向」を行方向だと勘違いしていたのだと思います。お恥ずかしい限りです。修正しておきました。ありがとうございます。m(_ _)m

  2. あとりえこばと より:

    【お知らせ】記事をリライトしました。実行結果でラベルやインデクスとデータが区別しやすいように、データの各要素に Element を意味する頭文字 E を添えました。記事の構成も一部変更しました。

  3. あとりえこばと より:

    【ChatGPT講義】panda.concateでデータフレームを結合します

    生徒: 先生、pandasのconcat()メソッドについて教えてください。concat()はどのような機能を持っていますか?
    先生: いい質問ですね!pandasのconcat()メソッドは、複数のデータフレームを縦方向または横方向に結合するための機能です。データフレーム同士を連結して新しいデータフレームを作成します。
    生徒: なるほど、データフレームを連結すると新しいデータフレームが作成されるんですね。具体的な使い方を教えていただけますか?
    先生: もちろんです!具体的な使い方を説明します。concat()メソッドは、連結するデータフレームをリストやタプルとして渡します。まず、縦方向の連結を考えてみましょう。

    import pandas as pd
    
    df1 = pd.DataFrame({'A': [1, 2, 3], 'B': [4, 5, 6]})
    df2 = pd.DataFrame({'A': [7, 8, 9], 'B': [10, 11, 12]})
    
    concatenated = pd.concat([df1, df2])

    この場合、df1とdf2は同じ列名を持つ2つのデータフレームです。concat()メソッドを使ってこれらを縦方向に連結すると、次のような結果が得られます。

       A   B
    0  1   4
    1  2   5
    2  3   6
    0  7  10
    1  8  11
    2  9  12

    連結された結果では、元のデータフレームの行が維持されています。インデックスも連続していることに注意してください。
    生徒: なるほど、連結するとインデックスも連続しているんですね。では、横方向に連結する方法はありますか?
    先生: はい、横方向に連結することも可能です。横方向の連結では、concat()メソッドの引数にaxis=1を指定します。

    concatenated = pd.concat([df1, df2], axis=1)

    この場合、df1とdf2は同じ行数を持つデータフレームです。concat()メソッドを使ってこれらを横方向に連結すると、次のような結果が得られます。

       A  B  A   B
    0  1  4  7  10
    1  2  5  8  11
    2