Python Pandasでテンプレートを活用してDataFrameに新しい行を追加する方法
PythonのPandasライブラリを使って、テンプレートを活用しながらDataFrameに新しい行を追加する方法を解説します。
はじめに
データエンジニアリングのスペシャリストとして働いていると、派生列(カラム)を作成する機会の方が、行(レコード)そのものを作成する機会よりも多くなりがちです。分析用データの生成や送信は、本来ならデータベースの専門チームが担当すべき役割だからです。しかし、常にそうとは限りません。
データ専門チームからの納品を待つ代わりに、サンプルとなる行を自分で作成しなければならない場面も出てきます。本記事では、行をスマートに作成するための便利なテクニックを紹介します。
実装の流れ
このレシピでは、まず小さなデータセットに対して.loc属性を使って行を追加する方法から始め、続いて.appendメソッドの使い方を見ていきます。
ステップ1:行を追加するためのDataFrameを作成する
まずは、後ほど行を追加していく基礎となるDataFrameを作成しましょう。
import pandas as pd
import numpy as np
players_info = pd.DataFrame(data=[
{"players": "Roger Federer", "titles": 20},
{"players": "Rafael Nadal", "titles": 20},
{"players": "Novak Djokovic", "titles": 17},
{"players": "Andy Murray", "titles": 3}], columns=["players", "titles"])出力結果
print(players_info.info())
<class 'pandas.core.frame.DataFrame'> RangeIndex: 4 entries, 0 to 3 Data columns (total 2 columns): # Column Non-Null Count Dtype --- ------ -------------- ----- 0 players 4 non-null object 1 titles 4 non-null int64 dtypes: int64(1), object(1) memory usage: 192.0+ bytes None
ステップ2:.loc属性で新しい選手を追加する
次に、.loc属性を使って新しい選手「Dominic Thiem」をDataFrameに追加してみましょう。
new_Player = ['Dominic Thiem', 1] players_info.loc[4] = new_Player
出力結果
print(players_info)
players titles 0 Roger Federer 20 1 Rafael Nadal 20 2 Novak Djokovic 17 3 Andy Murray 3 4 Dominic Thiem 1
ステップ3:辞書型で新しい行を追加する
同じく.loc属性を使って、今度は辞書型のデータを行として追加してみます。len(players_info)をインデックスに指定することで、常にDataFrameの末尾に追加できるのがポイントです。
new_player = {'players': 'Daniel Medvedev', 'titles': 0}
players_info.loc[len(players_info)] = new_player出力結果
print(players_info)
players titles 0 Roger Federer 20 1 Rafael Nadal 20 2 Novak Djokovic 17 3 Andy Murray 3 4 Dominic Thiem 1 5 Daniel Medvedev 0
ステップ4:Seriesオブジェクトで行を追加する
PandasのSeriesオブジェクトに格納したデータを追加することも可能です。
players_info.loc[len(players_info)] = pd.Series({'players': 'Andy Zverev', 'titles': 0})出力結果
print(players_info)
players titles 0 Roger Federer 20 1 Rafael Nadal 20 2 Novak Djokovic 17 3 Andy Murray 3 4 Dominic Thiem 1 5 Daniel Medvedev 0 6 Andy Zverev 0
まとめ:.locメソッドによる追加
ここまで4つのステップで.locメソッドを使ってデータを追加してきました。.loc属性は元のDataFrameを直接変更(in-place)する点が特徴です。
次に紹介するのは.appendメソッドです。こちらは呼び出し元のDataFrameを変更せず、行を追加した新しいコピーを返します。.appendの第一引数には、別のDataFrame、Series、辞書、またはリストを指定できます。
.appendメソッドの使い方と注意点
まずはインデックス付きのDataFrameを作成し直します。
# インデックス付きのDataFrameを作成
players_info = pd.DataFrame(data=[
{"players": "Roger Federer", "titles": 20},
{"players": "Rafael Nadal", "titles": 20},
{"players": "Novak Djokovic", "titles": 17},
{"players": "Andy Murray", "titles": 3}], columns=["players", "titles"],
index=["roger", "nadal", "djokovic", "murray"])続いて、辞書型のデータを.appendメソッドで追加してみます。
# 辞書型の新しい行を.appendメソッドで追加
players_info.append({'players': 'Daniel Medvedev', 'titles': 0})すると、以下のようなエラーが発生しました。
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
in
1 # Add a new row(dictionary) to DataFrame using .append method.
----> 2 players_info.append({'players': 'Daniel Medvedev', 'titles': 0})
TypeError: Can only append a Series if ignore_index=True or if the Series has a name辞書を追加しようとしたところ、「ignore_index=Trueパラメータを使うように」という例外が発生しました。指示通りにパラメータを追加して、挙動を確認してみましょう。
new_df = players_info.append({'players': 'Daniel Medvedev', 'titles': 0}, ignore_index=True)出力結果
print(f" *** Original with index \n {players_info} \n\n\n *** Modified index \n {new_df}")*** Original with index
players titles
roger Roger Federer 20
nadal Rafael Nadal 20
djokovic Novak Djokovic 17
murray Andy Murray 3
*** Modified index
players titles
0 Roger Federer 20
1 Rafael Nadal 20
2 Novak Djokovic 17
3 Andy Murray 3
4 Daniel Medvedev 0出力結果から何がわかるでしょうか?そう、ignore_index=Trueを設定すると、元のインデックスは完全に削除され、0からn-1までのRangeIndexに置き換えられます。
.appendメソッドは、複数の行を一度にまとめて追加したい場合に特に便利です。
player1 = pd.Series({'players': 'Andy Zverev', 'titles': 0}, name='zverev')
player2 = pd.Series({'players': 'Dominic Thiem', 'titles': 1}, name='theim')
new_df_1 = players_info.append([player1, player2])出力結果
print(new_df_1)
players titles roger Roger Federer 20 nadal Rafael Nadal 20 djokovic Novak Djokovic 17 murray Andy Murray 3 zverev Andy Zverev 0 theim Dominic Thiem 1
注意: DataFrame.append()メソッドはPandas 1.4以降で非推奨となり、Pandas 2.0で削除されました。最新バージョンでは、代わりにpd.concat([df, new_row], ignore_index=True)を使用してください。
多数のカラムを持つDataFrameへの行追加:テンプレート活用術
行追加の基本がわかったところで、次は多くのカラムを持つDataFrameへの行追加方法を見ていきましょう。
df = pd.read_csv("https://raw.githubusercontent.com/sasankac/TestDataSet/master/movies_data.csv")出力結果
print(df.info())
<class 'pandas.core.frame.DataFrame'> RangeIndex: 4803 entries, 0 to 4802 Data columns (total 12 columns): # Column Non-Null Count Dtype --- ------ -------------- ----- 0 budget 4803 non-null int64 1 id 4803 non-null int64 2 original_language 4803 non-null object 3 original_title 4803 non-null object 4 popularity 4803 non-null float64 5 release_date 4802 non-null object 6 revenue 4803 non-null int64 7 runtime 4801 non-null float64 8 status 4803 non-null object 9 title 4803 non-null object 10 vote_average 4803 non-null float64 11 vote_count 4803 non-null int64 dtypes: float64(3), int64(4), object(5) memory usage: 450.4+ KB None
このGoogle提供のデータセットには12個のカラムがあります。手作業で新しい行のデータを入力する場合、カラム名の入力ミスや入力忘れが起こりやすいのが実情です。この問題をどう回避すればよいのでしょうか?答えはシンプル、カラム名のテンプレートを作成することです。
columns_dictionary = df.iloc[0].to_dict()
出力結果
print(columns_dictionary)
{'budget': 237000000, 'id': 19995, 'original_language': 'en', 'original_title': 'Avatar', 'popularity': 150.437577, 'release_date': '10/12/2009', 'revenue': 2787965087, 'runtime': 162.0, 'status': 'Released', 'title': 'Avatar', 'vote_average': 7.2, 'vote_count': 11800}お気づきでしょうか?最初の行を取り出して辞書型に変換したのです。これでカラム名と値の両方が取得できました。次に、辞書内包表記を使って古い値をクリアします。文字列だった値は空文字列に、それ以外は欠損値(NaN)に置き換えましょう。
こうしてできた辞書は、これから入力したいあらゆる新規データのテンプレートとして使えます。
テンプレートの作成例
import datetime
new_data_dict = {}
for a, b in columns_dictionary.items():
if isinstance(b, str):
new_data_dict[a] = np.random.choice(list('abcde'))
elif isinstance(b, datetime.date):
new_data_dict[a] = np.nan
else:
new_data_dict[a] = np.nan出力結果
print(new_data_dict)
{'budget': nan, 'id': nan, 'original_language': 'e', 'original_title': 'a', 'popularity': nan, 'release_date': 'b', 'revenue': nan, 'runtime': nan, 'status': 'e', 'title': 'c', 'vote_average': nan, 'vote_count': nan}まとめ
本記事では、PandasのDataFrameに新しい行を追加する複数の方法を学びました。
- .loc属性:元のDataFrameを直接変更しながら行を追加できる。リスト・辞書・Seriesいずれにも対応。
- .appendメソッド:元のDataFrameを変更せず、新しいコピーを返す。複数行の一括追加に便利だが、最新のPandasでは
pd.concatへの移行が必要。 - テンプレート化:既存の行を辞書に変換して値をクリアしておけば、カラム数の多いDataFrameでも入力ミスを防げる。
特にカラム数の多い実務データでは、テンプレートを活用することで作業効率と正確性が大きく向上します。ぜひ日々のデータ処理に取り入れてみてください。
-
PythonでpandasのDataFrameをCSVファイルに書き込む方法【to_csv()の使い方】
pandasのDataFrameをCSVファイルに出力する基本 PythonでpandasのDataFrameをCSVファイルに書き込むには、to_csv()メソッドを使用します。このメソッドは、DataFrameの内容をそのままCSV形式で保存できる、最もシンプルで一般的な方法です。 まずはサンプルデータとして、リストを値にもつ辞書を作成しましょう。 # リストの辞書を定義 d = {Car: [BMW, Lexus, Audi, Mercedes, Jaguar, Bentley], Date_of_purchase: [2020-10-10, 2020-10-12, 2020-
-
【Python】Pandas DataFrameからnull(欠損値)行を削除する方法|dropna()の使い方
PandasのDataFrameからnull(NaN)行を削除するには、dropna()メソッドを使用します。この記事では、NaNを含むCSVファイルを読み込み、dropna()で欠損値を含む行を取り除くまでの手順を、サンプルコードと実行結果とともにわかりやすく解説します。前提:NaNを含むCSVファイル今回の例では、一部にNaN(null値)が含まれる以下のようなCSVファイル(CarRecords.csv)を使用します。手順1:read_csv()でCSVファイルを読み込むまずpandasをインポートし、read_csv()を使ってCSVファイルを読み込みます。ここではデスクトップ上に保存