Pandas

[Python] Pandas – DataFrameを結合するconcat()の使い方

Pandasのconcat()は、複数のDataFrameSeriesを結合するための関数です。

主に縦方向(行方向)や横方向(列方向)にデータを連結する際に使用されます。

concat()の基本的な使い方は、リスト形式で結合したいDataFrameSeriesを渡し、axis引数で結合方向を指定します。

axis=0で行方向(デフォルト)、axis=1で列方向に結合します。

ignore_index=Trueを指定すると、インデックスがリセットされます。

concat()とは?基本的な使い方

Pandasのconcat()関数は、複数のDataFrameやSeriesを結合するための非常に便利なツールです。

データの結合は、データ分析や前処理において重要なステップであり、concat()を使うことで、簡単にデータを統合できます。

ここでは、concat()の基本的な使い方を解説します。

concat()の概要

concat()は、Pandasライブラリの関数で、複数のDataFrameやSeriesを指定した軸に沿って結合します。

デフォルトでは、行方向(縦方向)に結合されますが、列方向(横方向)にも結合可能です。

concat()の基本構文

concat()の基本的な構文は以下の通りです。

import pandas as pd
result = pd.concat(objs, axis=0, join='outer', ignore_index=False, keys=None)
  • objs: 結合するDataFrameやSeriesのリスト
  • axis: 結合する軸(0: 行方向、1: 列方向)
  • join: 結合方法(‘outer’または’inner’)
  • ignore_index: インデックスを無視するかどうか(TrueまたはFalse)
  • keys: 階層的なインデックスを作成するためのキー

行方向の結合(axis=0)

行方向に結合する場合、axis=0を指定します。

以下は、2つのDataFrameを行方向に結合する例です。

import pandas as pd
# DataFrameの作成
df1 = pd.DataFrame({'A': [1, 2], 'B': [3, 4]})
df2 = pd.DataFrame({'A': [5, 6], 'B': [7, 8]})
# 行方向に結合
result = pd.concat([df1, df2], axis=0)
print(result)
   A  B
0  1  3
1  2  4
0  5  7
1  6  8

この例では、df1df2が行方向に結合され、新しいDataFrameが作成されました。

インデックスは元のDataFrameから引き継がれています。

列方向の結合(axis=1)

列方向に結合する場合、axis=1を指定します。

以下は、2つのDataFrameを列方向に結合する例です。

import pandas as pd
# DataFrameの作成
df1 = pd.DataFrame({'A': [1, 2]})
df2 = pd.DataFrame({'B': [3, 4]})
# 列方向に結合
result = pd.concat([df1, df2], axis=1)
print(result)
   A  B
0  1  3
1  2  4

この例では、df1df2が列方向に結合され、新しいDataFrameが作成されました。

インデックスの扱い(ignore_index)

ignore_index引数をTrueに設定すると、結合後のDataFrameのインデックスが再設定されます。

以下はその例です。

import pandas as pd
# DataFrameの作成
df1 = pd.DataFrame({'A': [1, 2]})
df2 = pd.DataFrame({'A': [3, 4]})
# 行方向に結合し、インデックスを無視
result = pd.concat([df1, df2], axis=0, ignore_index=True)
print(result)
   A
0  1
1  2
2  3
3  4

この例では、ignore_index=Trueにより、インデックスが0から始まる連続した値に再設定されました。

keysを使った階層的な結合

keys引数を使用すると、結合したDataFrameに階層的なインデックスを作成できます。

以下はその例です。

import pandas as pd
# DataFrameの作成
df1 = pd.DataFrame({'A': [1, 2]})
df2 = pd.DataFrame({'A': [3, 4]})
# 階層的に結合
result = pd.concat([df1, df2], axis=0, keys=['df1', 'df2'])
print(result)
       A
df1 0  1
    1  2
df2 0  3
    1  4

この例では、keysを使ってdf1df2のデータを階層的に結合し、インデックスにそれぞれのDataFrameの名前が付けられました。

concat()のオプション引数

concat()関数には、データの結合をより柔軟に行うためのオプション引数がいくつか用意されています。

これらの引数を使うことで、結合の挙動を細かく制御することができます。

ここでは、主なオプション引数について解説します。

join引数の使い方(innerとouter)

join引数は、結合時にどのようにインデックスを扱うかを指定します。

主に'outer''inner'の2つのオプションがあります。

  • outer: デフォルトの設定で、すべてのインデックスを保持し、存在しないインデックスにはNaNを挿入します。
  • inner: 共通のインデックスのみを保持し、存在しないインデックスは除外します。

以下は、join引数の使い方の例です。

import pandas as pd
# DataFrameの作成
df1 = pd.DataFrame({'A': [1, 2]}, index=[0, 1])
df2 = pd.DataFrame({'B': [3, 4]}, index=[1, 2])
# outer join
result_outer = pd.concat([df1, df2], join='outer', axis=0)
print("Outer Join:\n", result_outer)
# inner join
result_inner = pd.concat([df1, df2], join='inner', axis=0)
print("\nInner Join:\n", result_inner)
Outer Join:
Outer Join:
      A    B
0  1.0  NaN
1  2.0  NaN
1  NaN  3.0
2  NaN  4.0

Inner Join:
 Empty DataFrame
Columns: []
Index: [0, 1, 1, 2]

この例では、outerinnerの両方の結合方法を示しています。

outerではすべてのインデックスが保持され、innerでは共通のインデックスのみが表示されています。

sort引数で結合後の並びを制御

sort引数は、結合後のインデックスをソートするかどうかを指定します。

デフォルトではTrueに設定されており、インデックスがソートされます。

Falseに設定すると、元の順序が保持されます。

以下は、sort引数の使い方の例です。

import pandas as pd
# DataFrameの作成
df1 = pd.DataFrame({'A': [1, 2]}, index=[1, 0])
df2 = pd.DataFrame({'B': [3, 4]}, index=[2, 1])
# sort=True(デフォルト)
result_sorted = pd.concat([df1, df2], sort=True)
print("Sorted:\n", result_sorted)
# sort=False
result_unsorted = pd.concat([df1, df2], sort=False)
print("\nUnsorted:\n", result_unsorted)
Sorted:
      A    B
1  1.0  NaN
0  2.0  NaN
2  NaN  3.0
1  NaN  4.0

Unsorted:
      A    B
1  1.0  NaN
0  2.0  NaN
2  NaN  3.0
1  NaN  4.0

この例では、sort=Trueの場合はインデックスがソートされ、sort=Falseの場合は元の順序が保持されています。

verify_integrityで重複インデックスをチェック

verify_integrity引数は、結合後にインデックスが重複していないかをチェックするためのオプションです。

Trueに設定すると、重複がある場合にエラーが発生します。

デフォルトはFalseです。

以下は、verify_integrity引数の使い方の例です。

import pandas as pd
# DataFrameの作成
df1 = pd.DataFrame({'A': [1, 2]}, index=[0, 1])
df2 = pd.DataFrame({'B': [3, 4]}, index=[1, 2])
# verify_integrity=True(重複インデックスがあるためエラー)
try:
    result = pd.concat([df1, df2], verify_integrity=True)
except ValueError as e:
    print("Error:", e)
Error: Indexes have overlapping values: Index([1], dtype='int64')

この例では、verify_integrity=Trueにより、重複インデックスがあるためエラーが発生しました。

重複を許可しない場合に便利です。

copy引数の挙動

copy引数は、元のDataFrameをコピーするかどうかを指定します。

デフォルトはTrueで、元のデータをコピーします。

Falseに設定すると、元のデータを参照します。

これにより、メモリの使用量を削減できますが、元のデータが変更されると結合後のデータにも影響が出る可能性があります。

以下は、copy引数の使い方の例です。

import pandas as pd
# DataFrameの作成
df1 = pd.DataFrame({'A': [1, 2]})
df2 = pd.DataFrame({'B': [3, 4]})
# copy=True(デフォルト)
result_copy = pd.concat([df1, df2], copy=True)
print("Copy:\n", result_copy)
# copy=False
result_no_copy = pd.concat([df1, df2], copy=False)
print("\nNo Copy:\n", result_no_copy)
Copy:
      A    B
0  1.0  NaN
1  2.0  NaN
0  NaN  3.0
1  NaN  4.0

No Copy:
      A    B
0  1.0  NaN
1  2.0  NaN
0  NaN  3.0
1  NaN  4.0

この例では、copy引数の設定による違いは示されていませんが、copy=Falseに設定した場合、元のDataFrameが変更されると、結合後のDataFrameにも影響が出ることに注意が必要です。

concat()とmerge()の違い

Pandasにはデータを結合するための関数としてconcat()merge()がありますが、それぞれの機能や用途は異なります。

ここでは、これらの違いを詳しく解説します。

concat()とmerge()の基本的な違い

concat()merge()の主な違いは、結合の方法と目的にあります。

特徴concat()merge()
結合方法行または列方向に結合キーを基に結合
結合対象DataFrameやSeriesDataFrame
結合の種類縦または横の単純な結合SQLのJOINに似た複雑な結合
インデックスインデックスをそのまま保持指定したキーに基づいてインデックスを作成
使用例データのスタックや連結データの関連付けや結合

この表からもわかるように、concat()は主にデータを単純に結合するために使用され、merge()はデータの関連性を考慮して結合するために使用されます。

concat()が適しているケース

concat()は、以下のようなケースで特に有用です。

  • データのスタック: 複数のDataFrameを縦に結合して、1つの大きなDataFrameを作成したい場合。
  • データの連結: 列方向にデータを追加したい場合。
  • インデックスをそのまま保持: 元のインデックスを維持したままデータを結合したい場合。
  • データの前処理: データの前処理段階で、複数のデータセットをまとめたい場合。

例えば、異なる期間の売上データを1つのDataFrameにまとめる場合などにconcat()が適しています。

merge()が適しているケース

merge()は、以下のようなケースで特に有用です。

  • データの関連付け: 2つ以上のDataFrameを特定のキーに基づいて結合したい場合。
  • SQLのJOINのような操作: INNER JOINやOUTER JOINなど、複雑な結合を行いたい場合。
  • データの整合性を保つ: 特定の条件に基づいてデータを結合し、整合性を保ちたい場合。
  • 異なるデータソースの統合: 異なるデータソースからの情報を統合したい場合。

例えば、顧客情報と注文情報を顧客IDで結合する場合などにmerge()が適しています。

このように、concat()merge()はそれぞれ異なる目的に応じて使い分けることが重要です。

データの結合方法を理解し、適切な関数を選択することで、効率的なデータ処理が可能になります。

実践例:concat()を使ったデータ結合

concat()関数を使って、さまざまなデータ結合の実践例を見ていきましょう。

これにより、concat()の使い方をより具体的に理解できます。

複数のDataFrameを縦に結合する

複数のDataFrameを縦に結合する場合、axis=0を指定します。

以下は、2つのDataFrameを縦に結合する例です。

import pandas as pd
# DataFrameの作成
df1 = pd.DataFrame({'A': [1, 2], 'B': [3, 4]})
df2 = pd.DataFrame({'A': [5, 6], 'B': [7, 8]})
# 縦に結合
result = pd.concat([df1, df2], axis=0)
print(result)
   A  B
0  1  3
1  2  4
0  5  7
1  6  8

この例では、df1df2が縦に結合され、新しいDataFrameが作成されました。

インデックスは元のDataFrameから引き継がれています。

複数のDataFrameを横に結合する

複数のDataFrameを横に結合する場合、axis=1を指定します。

以下は、2つのDataFrameを横に結合する例です。

import pandas as pd
# DataFrameの作成
df1 = pd.DataFrame({'A': [1, 2]})
df2 = pd.DataFrame({'B': [3, 4]})
# 横に結合
result = pd.concat([df1, df2], axis=1)
print(result)
   A  B
0  1  3
1  2  4

この例では、df1df2が横に結合され、新しいDataFrameが作成されました。

異なるインデックスを持つDataFrameの結合

異なるインデックスを持つDataFrameを結合する場合でも、concat()を使うことができます。

以下はその例です。

import pandas as pd
# DataFrameの作成
df1 = pd.DataFrame({'A': [1, 2]}, index=[0, 1])
df2 = pd.DataFrame({'B': [3, 4]}, index=[2, 3])
# 縦に結合
result = pd.concat([df1, df2], axis=0)
print(result)
   A    B
0  1  NaN
1  2  NaN
2 NaN  3
3 NaN  4

この例では、df1df2が異なるインデックスを持っているため、結合後にNaNが挿入されています。

異なる列を持つDataFrameの結合

異なる列を持つDataFrameを結合する場合も、concat()を使用できます。

以下はその例です。

import pandas as pd
# DataFrameの作成
df1 = pd.DataFrame({'A': [1, 2]})
df2 = pd.DataFrame({'B': [3, 4]})
# 縦に結合
result = pd.concat([df1, df2], axis=0)
print(result)
     A    B
0  1.0  NaN
1  2.0  NaN
0  NaN  3.0
1  NaN  4.0

この例では、df1df2が異なる列を持っているため、結合後にNaNが挿入されています。

SeriesとDataFrameの結合

concat()はSeriesとDataFrameを結合することもできます。

以下はその例です。

import pandas as pd
# DataFrameとSeriesの作成
df = pd.DataFrame({'A': [1, 2]})
s = pd.Series([3, 4], name='B')
# 縦に結合
result = pd.concat([df, s], axis=1)
print(result)
   A  B
0  1  3
1  2  4

この例では、DataFrame dfとSeries sが横に結合され、新しいDataFrameが作成されました。

Seriesは自動的に列名が付けられます。

これらの実践例を通じて、concat()関数の使い方やデータ結合の方法を理解できたと思います。

さまざまなデータセットを扱う際に、これらのテクニックを活用してください。

応用例:concat()を使った高度なデータ操作

concat()関数は、基本的なデータ結合だけでなく、さまざまな高度なデータ操作にも利用できます。

ここでは、いくつかの応用例を紹介します。

複数のDataFrameを階層的に結合する

concat()keys引数を使用すると、複数のDataFrameを階層的に結合することができます。

これにより、データのグループ化が容易になります。

以下はその例です。

import pandas as pd
# DataFrameの作成
df1 = pd.DataFrame({'A': [1, 2]})
df2 = pd.DataFrame({'A': [3, 4]})
# 階層的に結合
result = pd.concat([df1, df2], keys=['Group1', 'Group2'])
print(result)
          A
Group1 0  1
       1  2
Group2 0  3
       1  4

この例では、df1df2が階層的に結合され、各グループのデータが明確に区別されています。

データの一部を条件付きで結合する

条件に基づいてデータを結合する場合、まず条件を満たすDataFrameをフィルタリングし、その後concat()を使用します。

以下はその例です。

import pandas as pd
# DataFrameの作成
df1 = pd.DataFrame({'A': [1, 2, 3], 'B': [4, 5, 6]})
df2 = pd.DataFrame({'A': [7, 8, 9], 'B': [10, 11, 12]})
# 条件に基づいてフィルタリング
filtered_df1 = df1[df1['A'] > 1]
# 結合
result = pd.concat([filtered_df1, df2], axis=0)
print(result)
   A   B
1  2   5
2  3   6
0  7  10
1  8  11
2  9  12

この例では、df1から条件を満たす行をフィルタリングし、その後df2と結合しています。

データの結合後にフィルタリングを行う

データを結合した後に、特定の条件に基づいてフィルタリングを行うことも可能です。

以下はその例です。

import pandas as pd
# DataFrameの作成
df1 = pd.DataFrame({'A': [1, 2], 'B': [4, 5]})
df2 = pd.DataFrame({'A': [3, 4], 'B': [6, 7]})
# 結合
result = pd.concat([df1, df2], axis=0)
# 結合後にフィルタリング
filtered_result = result[result['A'] > 2]
print(filtered_result)
   A  B
1  3  6
2  4  7

この例では、結合後のDataFrameからAの値が2より大きい行をフィルタリングしています。

concat()を使った時系列データの結合

時系列データを扱う場合、concat()を使って異なる期間のデータを結合することができます。

以下はその例です。

import pandas as pd
# 時系列データの作成
date_range1 = pd.date_range(start='2023-01-01', periods=3)
date_range2 = pd.date_range(start='2023-01-04', periods=3)
df1 = pd.DataFrame({'Value': [1, 2, 3]}, index=date_range1)
df2 = pd.DataFrame({'Value': [4, 5, 6]}, index=date_range2)
# 時系列データを結合
result = pd.concat([df1, df2])
print(result)
            Value
2023-01-01      1
2023-01-02      2
2023-01-03      3
2023-01-04      4
2023-01-05      5
2023-01-06      6

この例では、異なる期間の時系列データを結合し、1つのDataFrameにまとめています。

大規模データの効率的な結合

大規模データを扱う場合、concat()を使用することでメモリ効率を考慮した結合が可能です。

copy=Falseを指定することで、元のデータをコピーせずに結合できます。

以下はその例です。

import pandas as pd
# 大規模DataFrameの作成
df1 = pd.DataFrame({'A': range(1000000), 'B': range(1000000)})
df2 = pd.DataFrame({'A': range(1000000, 2000000), 'B': range(1000000, 2000000)})
# 大規模データを効率的に結合
result = pd.concat([df1, df2], copy=False)
print(result)
A      B
0        0      0
1        1      1
2        2      2
...    ...    ...
1999997  1999997  1999997
1999998  1999998  1999998
1999999  1999999  1999999

この例では、copy=Falseを指定することで、メモリの使用量を削減しつつ大規模データを結合しています。

これらの応用例を通じて、concat()関数の柔軟性と強力さを理解できたと思います。

さまざまなデータ操作において、concat()を活用して効率的なデータ処理を行ってください。

concat()を使う際の注意点

concat()関数は非常に便利ですが、使用する際にはいくつかの注意点があります。

これらの注意点を理解しておくことで、データ結合の際のトラブルを避けることができます。

以下に、主な注意点を解説します。

インデックスの重複に注意

concat()を使用して複数のDataFrameを結合する際、インデックスが重複する可能性があります。

特に、ignore_index引数をFalseに設定した場合、元のDataFrameのインデックスがそのまま引き継がれるため、重複が発生することがあります。

重複したインデックスは、データの整合性を損なう可能性があるため、注意が必要です。

import pandas as pd
# DataFrameの作成
df1 = pd.DataFrame({'A': [1, 2]}, index=[0, 1])
df2 = pd.DataFrame({'B': [3, 4]}, index=[1, 2])
# 縦に結合
result = pd.concat([df1, df2], axis=0)
print(result)
     A    B
0  1.0  NaN
1  2.0  NaN
1  NaN  3.0
2  NaN  4.0

この例では、インデックス1が重複しているため、データの整合性に注意が必要です。

重複を避けるためには、ignore_index=Trueを設定するか、インデックスを適切にリセットすることが推奨されます。

データ型の不一致に注意

異なるDataFrameを結合する際、列のデータ型が一致しない場合があります。

concat()はデフォルトでデータ型を自動的に推測しますが、異なるデータ型が混在すると、意図しない結果を招くことがあります。

特に、数値と文字列が混在する場合、NaNが挿入されることがあります。

import pandas as pd
# DataFrameの作成
df1 = pd.DataFrame({'A': [1, 2]})
df2 = pd.DataFrame({'A': ['3', '4']})  # 文字列型
# 縦に結合
result = pd.concat([df1, df2], axis=0)
print(result)
   A
0  1
1  2
0  3
1  4

この例では、df1の列Aは整数型で、df2の列Aは文字列型です。

結合後、データ型が混在しているため、注意が必要です。

データ型を統一するためには、結合前にデータ型を明示的に変換することが推奨されます。

メモリ使用量に注意

大規模なDataFrameを結合する際、メモリ使用量が増加することがあります。

特に、copy=True(デフォルト設定)の場合、元のDataFrameのコピーが作成されるため、メモリを多く消費します。

大規模データを扱う場合は、copy=Falseを設定することで、メモリ使用量を削減できますが、元のデータが変更されると結合後のデータにも影響が出る可能性があるため、注意が必要です。

import pandas as pd
# 大規模DataFrameの作成
df1 = pd.DataFrame({'A': range(1000000), 'B': range(1000000)})
df2 = pd.DataFrame({'A': range(1000000, 2000000), 'B': range(1000000, 2000000)})
# 大規模データを効率的に結合
result = pd.concat([df1, df2], copy=False)
print(result)
              A        B
0             0        0
1             1        1
2             2        2
3             3        3
4             4        4
...         ...      ...
999995  1999995  1999995
999996  1999996  1999996
999997  1999997  1999997
999998  1999998  1999998
999999  1999999  1999999

[2000000 rows x 2 columns]

この例では、copy=Falseを指定することで、メモリの使用量を削減していますが、元のDataFrameが変更されると、結合後のDataFrameにも影響が出ることに注意が必要です。

これらの注意点を理解し、適切に対処することで、concat()を使ったデータ結合をより効果的に行うことができます。

データの整合性やメモリ管理に気を配りながら、データ処理を進めていきましょう。

まとめ

この記事では、Pandasのconcat()関数を使ったデータ結合の基本から応用までを詳しく解説しました。

具体的には、複数のDataFrameを縦や横に結合する方法、異なるインデックスや列を持つDataFrameの結合、さらには条件付きでの結合や時系列データの扱いについても触れました。

これらの知識を活用して、データ処理や分析の効率を向上させるために、実際のプロジェクトでconcat()を積極的に利用してみてください。

関連記事

Back to top button