Pandasのappendでデータを効率的に追加する方法を解説

はじめに

Pandasは、データの操作や分析を容易にするPythonのライブラリです。
かつては、データを追加するためのappend関数がよく利用されていましたが、
Pandas 1.4.0以降ではappend関数は非推奨(deprecated)となり
Pandas 2.0系では完全に削除されています

この記事では、append関数がどのような役割を果たしていたかを整理しつつ、
現在推奨されるpd.concatによるデータ追加方法や、
インデックス・カラムの扱い、大量データに対する効率的な追加方法について解説します。
すでにappendを使ったコードを書いている方が、安全にpd.concatへ移行するためのポイントも紹介します。

Pandasのappend関数の現状と利用目的

append関数は、もともとSeriesやDataFrameに新しいデータを「後ろに足す」ためのメソッドでした。
しかし、内部的にはpd.concatとほぼ同じ処理を行っており、特にループ内で繰り返し呼び出すと、
パフォーマンスが低下しやすいという問題がありました。

このため、Pandas 1.4.0以降では
DataFrame.appendSeries.appendが非推奨となり、代わりに
pd.concatを使うことが公式に推奨されています。
新しくコードを書く場合は、appendではなくpd.concatを前提に設計するようにしましょう。

appendの基本的な挙動とpd.concatへの書き換え

ここでは、従来のappendの挙動と、それをどのようにpd.concatで書き換えればよいかを解説します。
すでにappendを使っているコードがある場合は、以下のパターンを参考にリファクタリングしてください。

Seriesへのデータ追加:appendからpd.concatへの移行

まずは、Series同士を結合する例です。

(従来の書き方:appendを使う例・現在は非推奨)

import pandas as pd

s1 = pd.Series([1, 2, 3])
s2 = pd.Series([4, 5, 6])

# 旧来の書き方(現在は非推奨)
# s3 = s1.append(s2)

(現在推奨される書き方:pd.concatを使う)

import pandas as pd

s1 = pd.Series([1, 2, 3])
s2 = pd.Series([4, 5, 6])

# pd.concatを使って結合する
s3 = pd.concat([s1, s2])

print(s3)

DataFrameへのデータ追加:appendからpd.concatへの移行

次に、DataFrame同士を縦方向に結合する例です。

(従来の書き方:appendを使う例・現在は非推奨)

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]})

# 旧来の書き方(現在は非推奨)
# df3 = df1.append(df2, ignore_index=True)

(現在推奨される書き方:pd.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]})

# pd.concatで縦方向(行方向)に結合する
df3 = pd.concat([df1, df2], ignore_index=True)

print(df3)

多くの場合、df1.append(df2, ignore_index=True)
pd.concat([df1, df2], ignore_index=True)に置き換えることができます。
複数のDataFrameをまとめて結合したい場合も、同様にリストにして渡します。

インデックスとカラムの整合性:pd.concat利用時の注意点

appendのときと同様に、pd.concatを使う場合もインデックスやカラム(列名)の整合性に注意が必要です。

インデックスが重複する場合

インデックスを指定せずに結合すると、元のインデックスが維持されるため、
インデックスが重複することがあります。

import pandas as pd

df1 = pd.DataFrame({"A": [1, 2, 3], "B": [4, 5, 6]}, index=[0, 1, 2])
df2 = pd.DataFrame({"A": [7, 8, 9], "B": [10, 11, 12]}, index=[2, 3, 4])

df3 = pd.concat([df1, df2])

print(df3)
   A   B
0  1   4
1  2   5
2  3   6
2  7  10
3  8  11
4  9  12

上記のように、インデックス2が重複していることがわかります。
インデックスの重複を避けたい場合は、ignore_index=Trueを指定して、
インデックスを振り直すのが一般的です。

df3 = pd.concat([df1, df2], ignore_index=True)
print(df3)

カラム(列名)が揃っていない場合

pd.concatは、すべてのカラムを結合対象として扱うため、
どちらか一方にしか存在しないカラムは、そのDataFrame側だけ値が入り、
もう片方は欠損値(NaN)になります。

列構造が異なるDataFrameを結合する場合は、
事前にカラム名を揃える、あるいは必要なカラムだけを選択してから結合するようにしましょう。

大量データを扱う場合の効率的な追加方法

append(およびpd.concat)をループの中で毎回呼び出すと、
DataFrameのコピーが何度も発生するため非常に非効率になります。
大量データの場合は、次のようなパターンを使うことで高速化が期待できます。

パターン1:一度リストに貯めてからまとめてconcatする

最もよく使われるパターンは、「一度Pythonのリストに貯めてから最後に一括でconcatする」方法です。

import pandas as pd
import numpy as np

# 元のデータ
data = np.random.rand(100000, 3)
df = pd.DataFrame(data, columns=["A", "B", "C"])

# 追加するデータを複数回生成すると仮定
dfs_to_add = []

for i in range(10):
    new_data = np.random.rand(10000, 3)
    new_df = pd.DataFrame(new_data, columns=["A", "B", "C"])
    dfs_to_add.append(new_df)

# 最後にまとめて結合
df_extended = pd.concat([df] + dfs_to_add, ignore_index=True)

print(df_extended)

この方法では、ループ内ではリスト操作だけを行い、
DataFrameの結合は一度だけに抑えられます。
その結果、appendを毎回呼び出すよりも大幅に高速になります。

パターン2:最初からDataFrameをまとめて作る

データがNumPy配列やリストとして一括で用意できる場合は、
そもそもDataFrameを分割せず、最初からまとめてDataFrameを作るのが最も効率的です。

import pandas as pd
import numpy as np

# まとめてデータを生成
all_data = np.random.rand(200000, 3)

df = pd.DataFrame(all_data, columns=["A", "B", "C"])

一見回り道に見えても、「まとめて作る」「まとめて結合する」という設計に変えることで、
大量データ処理の性能が大きく向上します。

appendと他の結合方法との比較:concatやmergeの使い分け

Pandasには、データを結合するための関数がいくつか存在します。
appendはその一つでしたが、現在はpd.concatやmergeなどを用途に応じて使い分けるのが基本です。

pd.concat:単純な「縦・横結合」に向いている

  • 複数のSeriesやDataFrameを縦方向(行方向)または横方向(列方向)に結合する。
  • インデックスやカラムをどのように扱うかを、axisignore_indexなどで制御できる。
  • appendの主な役割は、ほぼpd.concatで代替可能。

merge:SQLのJOINのような結合に向いている

  • 共通のキー(列)やインデックスをもとに、複数のDataFrameを結合する。
  • SQLのINNER JOIN / LEFT JOIN / RIGHT JOIN / OUTER JOINに相当する処理が可能。
  • 単純な「足し合わせ」ではなく、キーに基づいて意味のある結合を行いたい場合に使用する。

まとめ:appendの代わりに何を使うべきか

  • 行や列を単純に追加したい → pd.concat
  • キー(IDや日付など)を使って結合したい → merge
  • 大量データをループで追加したい → 一度リストに貯めてからconcat

まとめ

この記事では、Pandasのappend関数と、その現在の位置づけ、および代替手段について解説しました。

  • append関数(DataFrame.append / Series.append)は、Pandas 1.4.0以降で非推奨となり、Pandas 2.0系では削除されています。
  • 新しくコードを書く場合や既存コードを保守する場合は、pd.concatを基本として使うのが推奨です。
  • インデックスやカラムの整合性、ignore_indexの指定などを適切に行うことで、安全にデータを追加できます。
  • 大量データを扱う場合は、ループ内での連続concat/appendを避け、一度リストに集約してからまとめてconcatするなどの工夫が重要です。
  • 用途に応じて、concat・mergeなどの関数を使い分けることで、読みやすく効率的なコードを書けます。

もし手元のコードでappend関数を使っている場合は、本記事を参考に、
pd.concatやmergeを用いた最新の書き方へ少しずつ移行してみてください。
そうすることで、将来のPandasのアップデートにも対応しやすくなり、パフォーマンスや保守性の面でもメリットがあります。