Pandas入門:データフレーム操作の基本をマスターしよう!【初心者向け】
こんにちは!Pythonを使ったデータ分析の世界へようこそ。データ分析ライブラリの定番であるPandasは、データを効率的に扱うための強力なツールです。特に、データフレーム (DataFrame) は、Excelの表のような2次元データを扱う中心的な役割を担います。
この記事では、Python初心者の方に向けて、Pandasのデータフレームの基本的な操作方法(データの選択、追加、削除など)を、具体的なコード例と実行結果を交えながら分かりやすく解説します。
準備:Pandasのインストールとインポート
まず、Pandasライブラリがインストールされていない場合は、ターミナル(WindowsならコマンドプロンプトやPowerShell、Macならターミナル)で以下のコマンドを実行してインストールします。
pip install pandas
PythonスクリプトやJupyter NotebookでPandasを使うには、最初にインポートするのが一般的です。pd
という別名をつけてインポートするのが慣例です。
import pandas as pd
サンプルデータフレームの作成
操作を学ぶために、まずは簡単なサンプルデータフレームを作成しましょう。ここでは、生徒のテスト結果を模したデータを作成します。
import pandas as pd
# データフレームの元になる辞書データ
data = {'名前': ['佐藤', '鈴木', '高橋', '田中'],
'科目': ['数学', '英語', '国語', '数学'],
'点数': [85, 92, 78, 88]}
# データフレームを作成
df = pd.DataFrame(data)
# データフレームを表示
print("--- 元のデータフレーム ---")
print(df)
実行結果:
--- 元のデータフレーム ---
名前 科目 点数
0 佐藤 数学 85
1 鈴木 英語 92
2 高橋 国語 78
3 田中 数学 88
このdf
というデータフレームを使って、様々な操作を見ていきましょう。左端の0, 1, 2, 3
はインデックスと呼ばれ、各行を識別するためのラベルです。
データの選択(参照)
データフレームから特定のデータを取り出す方法を学びます。
1. 列を選択する
特定の列のデータを取得するには、df['列名']
のように記述します。
コード例 (1列選択):
# '名前'列を選択
name_column = df['名前']
print("--- '名前'列 ---")
print(name_column)
実行結果:
--- '名前'列 ---
0 佐藤
1 鈴木
2 高橋
3 田中
Name: 名前, dtype: object
- 解説: 1列だけを選択すると、シリーズ (Series) という1次元のデータ構造で結果が返されます。
複数の列を選択する場合は、列名のリストを []
で囲んで指定します df[['列名1', '列名2']]
。
コード例 (複数列選択):
# '名前'列と'点数'列を選択
subset = df[['名前', '点数']]
print("--- '名前'列と'点数'列 ---")
print(subset)
実行結果:
--- '名前'列と'点数'列 ---
名前 点数
0 佐藤 85
1 鈴木 92
2 高橋 78
3 田中 88
- 解説 (
[[]]
の謎を解明!): なぜブラケット[]
が二重になっているのか、ステップバイステップで見ていきましょう。df[['名前', '点数']]
というコードは、実際には2段階で処理されています。- ステップ1: 内側の
['名前', '点数']
の処理- まず、Pythonは内側の
['名前', '点数']
を解釈します。これはPandasの特別な機能ではなく、Pythonの基本的なリストを作成するための書き方(リストリテラル)です。 - この部分が実行されると、メモリ上に
'名前'
と'点数'
という2つの文字列を要素として持つリストオブジェクトが一時的に作られます。イメージとしては、temp_list = ['名前', '点数']
のような変数にリストが代入される感じです。 - この時点では、まだデータフレーム
df
は何も操作されていません。単に「どの列が欲しいか」を示すリストが準備されただけです。
- まず、Pythonは内側の
- ステップ2: 外側の
df[リスト]
の処理- 次に、外側の
df[]
が、ステップ1で作られたリストオブジェクト (['名前', '点数']
) を引数として受け取ります。 - データフレームの
[]
(添え字演算子と呼ばれます) は、引数として単一の列名(文字列)を受け取るとその列(シリーズ)を返しますが、引数として列名のリストを受け取ると、そのリストに含まれるすべての列を抽出して、新しいデータフレームを返すように設計されています。 - つまり、
df[]
は「お、引数はリストだな。リストの中身は ‘名前’ と ‘点数’ か。よし、元のデータフレームから ‘名前’ 列と ‘点数’ 列だけを取り出して、新しい表(データフレーム)を作って返そう」と動作します。
- 次に、外側の
なぜ
df[df[]]
ではないの?df['名前']
は ‘名前’ という列名の文字列を渡していますが、これは単一の列(シリーズ)を返します。df[]
の中にさらにdf[]
を入れる、例えばdf[df['名前']]
のような形は、意図した動作(複数列選択)にはなりません。なぜなら、外側のdf[]
は、引数として「列名のリスト」を期待しているからです。df['名前']
が返すシリーズオブジェクトを直接渡しても、「どの列を選べばいいか」の指示にはならないため、エラーになるか、意図しない行選択(ブールインデックス参照など特殊なケース)として解釈される可能性があります。結論として、
df[['列名1', '列名2']]
は、「まず欲しい列名のリストを作り、そのリストをデータフレームの選択機能に渡す」という2段階の処理を一文で書いている、と理解すると分かりやすいでしょう。 複数列を選択する場合は、必ず列名の「リスト」を渡す必要があるため、[[]]
という形になるのです。 - ステップ1: 内側の
2. 行を選択する (loc, iloc)
特定の行を選択するには、主に loc
と iloc
という2つの方法があります。
loc
: ラベル(インデックス名や列名)に基づいてデータを選択します。iloc
: 整数(行番号や列番号、0から始まる)に基づいてデータを選択します。
loc を使った行選択
コード例 (1行選択):
# インデックスラベル '1' の行を選択
row_1 = df.loc[1]
print("--- インデックス '1' の行 ---")
print(row_1)
実行結果:
--- インデックス '1' の行 ---
名前 鈴木
科目 英語
点数 92
Name: 1, dtype: object
- 解説: 1行だけを選択すると、シリーズ (Series) で返されます。インデックスが列名になります。
コード例 (複数行選択):
# インデックスラベル '0' と '2' の行を選択
rows_0_2 = df.loc[[0, 2]]
print("--- インデックス '0', '2' の行 ---")
print(rows_0_2)
実行結果:
--- インデックス '0', '2' の行 ---
名前 科目 点数
0 佐藤 数学 85
2 高橋 国語 78
- 解説: 複数行を選択すると、データフレームで返されます。ここでも選択したい行ラベルのリスト
[0, 2]
を渡していますね。
iloc を使った行選択
コード例 (1行選択):
# 2番目 (インデックス番号 1) の行を選択
row_iloc_1 = df.iloc[1]
print("--- 2番目の行 (iloc[1]) ---")
print(row_iloc_1)
実行結果:
--- 2番目の行 (iloc[1]) ---
名前 鈴木
科目 英語
点数 92
Name: 1, dtype: object
コード例 (複数行選択 スライス):
# 2番目から3番目まで (インデックス番号 1 から 2 まで) の行を選択
# スライスの場合、ilocでは終了位置を含まない (1 <= index < 3)
rows_iloc_slice = df.iloc[1:3]
print("--- 2番目から3番目の行 (iloc[1:3]) ---")
print(rows_iloc_slice)
実行結果:
--- 2番目から3番目の行 (iloc[1:3]) ---
名前 科目 点数
1 鈴木 英語 92
2 高橋 国語 78
loc
とiloc
の使い分け:- インデックスラベルが数値以外(例えば日付や文字列)の場合や、ラベル名で明確に指定したい場合は
loc
を使います。 - 行の「何番目か」で指定したい場合は
iloc
を使います。 - スライス(範囲指定)する場合、
loc
は終了ラベルを含み、iloc
は終了番号を含まない点に注意が必要です。
- インデックスラベルが数値以外(例えば日付や文字列)の場合や、ラベル名で明確に指定したい場合は
3. 特定の要素を選択する
行と列を同時に指定することで、特定のセルの値を取得できます。
コード例 (loc
):
# インデックス '1', 列 '科目' の値を取得
value_loc = df.loc[1, '科目']
print(f"--- loc[1, '科目'] の値 ---")
print(value_loc)
実行結果:
--- loc[1, '科目'] の値 ---
英語
コード例 (iloc
):
# 2行目 (index 1), 3列目 (index 2) の値を取得
value_iloc = df.iloc[1, 2]
print(f"--- iloc[1, 2] の値 ---")
print(value_iloc)
実行結果:
--- iloc[1, 2] の値 ---
92
4. 条件に合う行を選択する(フィルタリング)
特定の条件を満たす行だけを抽出することも非常によく使われます。
コード例:
# '点数' が 80点より大きい行を選択
high_scores = df[df['点数'] > 80]
print("--- 点数が80より大きい行 ---")
print(high_scores)
実行結果:
--- 点数が80より大きい行 ---
名前 科目 点数
0 佐藤 数学 85
1 鈴木 英語 92
3 田中 数学 88
- 解説:
df['点数'] > 80
は、各行の点数が80より大きいかどうかを示すブール値(True/False)のシリーズを返します。これをdf[...]
の中に指定すると、Trueに対応する行だけが抽出されます。これもデータフレームの[]
の便利な使い方の一つです。
データの追加
既存のデータフレームに新しい列を追加する方法を見ていきましょう。(行の追加は少し複雑になるため、別の記事で詳しく解説します。)
1. 列を追加する
新しい列を追加するには、df['新しい列名'] = 値のリストやシリーズ
のように代入します。
コード例:
# '評価' 列を追加 (点数が80以上なら'良', それ未満なら'可')
# 1. まず、各行の評価結果を格納するための空のリストを準備します。
grades = []
# 2. データフレーム df の '点数' 列から、点数を一つずつ取り出して処理します (forループ)。
for score in df['点数']:
# 3. 取り出した点数 (score) が 80 以上かどうかを判断します (if文)。
if score >= 80:
# 4. 80点以上の場合: リスト grades の末尾に '良' という文字列を追加します。
grades.append('良')
else:
# 5. 80点未満の場合: リスト grades の末尾に '可' という文字列を追加します。
grades.append('可')
# 6. ループが終わると、grades リストには ['良', '良', '可', '良'] という評価結果が格納されています。
# このリストを、データフレーム df の新しい列 '評価' として代入します。
df['評価'] = grades
# 7. データフレームを確認します。
print("--- '評価' 列を追加後 ---")
print(df)
実行結果:
--- '評価' 列を追加後 ---
名前 科目 点数 評価
0 佐藤 数学 85 良
1 鈴木 英語 92 良
2 高橋 国語 78 可
3 田中 数学 88 良
- 解説: 上記のコードにより、新しい列
評価
がデータフレームに追加されました。forループとif文を使って、各行の点数に応じた評価('良'または'可')を計算し、それを新しい列として追加しています。
このように、既存の列のデータを使って新しい列を作成することは、データ分析で頻繁に行われます。代入するリスト(ここでは `grades`)の要素数は、データフレームの行数と一致している必要があります。
データの削除 (drop)
データフレームから不要な行や列を削除するには、drop()
メソッドを使用します。
drop() メソッドの解説
- 目的 (Purpose): 指定されたラベル(インデックス名や列名)を持つ行または列を削除します。
- 用途 (Use Cases):
- 不要な行を削除する。
- 不要な列を削除する。
- 主な引数 (Arguments):
labels
: 削除したい行のインデックスラベル、または列の列名を指定します。単一のラベルまたはラベルのリストを指定できます。axis
: 削除対象が行か列かを指定します。0
または'index'
(デフォルト):labels
で指定されたインデックスラベルを持つ行を削除します。1
または'columns'
:labels
で指定された列名を持つ列を削除します。
index
:axis=0
と同じ意味で、削除したい行のインデックスラベルを指定します。(labels
とaxis=0
の組み合わせの代替)columns
:axis=1
と同じ意味で、削除したい列の列名を指定します。(labels
とaxis=1
の組み合わせの代替)inplace
:False
(デフォルト): 元のデータフレームは変更せず、行/列を削除した新しいデータフレームを返します。True
: 元のデータフレームを直接変更し、何も返しません (None
)。
1. 列を削除する
列を削除するには、drop()
メソッドで axis=1
を指定します。
コード例:
# 先ほど追加した '評価' 列を削除してみましょう。
# inplace=False (デフォルト) なので、元の df は変更されません。
df_dropped_column = df.drop('評価', axis=1)
print("--- '評価' 列を削除した新しいデータフレーム ---")
print(df_dropped_column)
# 元のデータフレーム df が変更されていないことを確認します。
print("\n--- 元のデータフレーム (変更なし) ---")
print(df)
実行結果:
--- '評価' 列を削除した新しいデータフレーム ---
名前 科目 点数
0 佐藤 数学 85
1 鈴木 英語 92
2 高橋 国語 78
3 田中 数学 88
--- 元のデータフレーム (変更なし) ---
名前 科目 点数 評価
0 佐藤 数学 85 良
1 鈴木 英語 92 良
2 高橋 国語 78 可
3 田中 数学 88 良
- 解説:
axis=1
を指定して評価
列を削除しました。inplace=False
(デフォルト) なので、drop()
は評価
列が削除された新しいデータフレーム (df_dropped_column
) を返します。元のdf
は変更されていません。
もし元のデータフレームを直接変更したい場合は inplace=True
を指定します。
コード例 (inplace=True
):
# '評価' 列を削除 (inplace=True なので元のdfが直接変更される)
print("--- inplace=True で削除する前のdf ---")
print(df)
df.drop('評価', axis=1, inplace=True)
print("\n--- '評価' 列を削除後 (inplace=True) ---")
print(df) # df 自体が変更されたことを確認
実行結果:
--- inplace=True で削除する前のdf ---
名前 科目 点数 評価
0 佐藤 数学 85 良
1 鈴木 英語 92 良
2 高橋 国語 78 可
3 田中 数学 88 良
--- '評価' 列を削除後 (inplace=True) ---
名前 科目 点数
0 佐藤 数学 85
1 鈴木 英語 92
2 高橋 国語 78
3 田中 数学 88
- 解説:
inplace=True
を指定したため、df
自体から評価
列が削除されました。初心者のうちは、意図しない変更を防ぐために `inplace=False` (デフォルト) を使い、結果を新しい変数に代入する方法をおすすめします。
2. 行を削除する
行を削除するには、drop()
メソッドで削除したい行のインデックスラベルを指定します (axis=0
はデフォルトなので省略可)。
コード例:
# インデックス '2' (高橋さん) の行を削除
# axis=0 はデフォルトなので省略可能です
df_dropped_rows = df.drop(2) # または df.drop(2, axis=0)
print("--- インデックス 2 の行を削除後 ---")
print(df_dropped_rows)
# 複数の行を削除する場合はリストで指定します
df_dropped_multi_rows = df.drop([0, 3]) # 佐藤さん(0)と田中さん(3)を削除
print("\n--- インデックス 0, 3 の行を削除後 ---")
print(df_dropped_multi_rows)
print("\n--- 元のデータフレーム (変更なし) ---")
print(df) # 元のdfは変更されていないことを確認
実行結果:
--- インデックス 2 の行を削除後 ---
名前 科目 点数
0 佐藤 数学 85
1 鈴木 英語 92
3 田中 数学 88
--- インデックス 0, 3 の行を削除後 ---
名前 科目 点数
1 鈴木 英語 92
2 高橋 国語 78
--- 元のデータフレーム (変更なし) ---
名前 科目 点数
0 佐藤 数学 85
1 鈴木 英語 92
2 高橋 国語 78
3 田中 数学 88
- 解説: インデックスラベル
2
を指定してその行を削除したり、インデックスラベルのリスト[0, 3]
を指定して複数の行を削除したりしました。ここでもinplace=False
(デフォルト) なので、元のdf
は変更されていません。
まとめ
今回は、Pandasのデータフレームの基本的な操作として、以下の方法を学びました。
- データの選択:
- 列の選択:
df['列名']
(単一列、Series),df[['列名1', '列名2']]
(複数列、DataFrame) - 行の選択:
df.loc[ラベル or ラベルリスト]
,df.iloc[位置 or 位置リスト or スライス]
- 特定要素の選択:
df.loc[行ラベル, 列ラベル]
,df.iloc[行位置, 列位置]
- 条件による選択 (フィルタリング):
df[条件式 (ブール値のSeries)]
- 列の選択:
- データの追加:
- 列の追加:
df['新しい列名'] = 値リスト or Series
- 列の追加:
- データの削除:
- 列の削除:
df.drop('列名' or 列名リスト, axis=1)
- 行の削除:
df.drop(インデックスラベル or ラベルリスト, axis=0)
(axis=0は省略可)
- 列の削除:
これらの基本操作は、Pandasを使ったデータ分析の第一歩です。繰り返しコードを実行し、データフレームがどのように変化するかを確認しながら、操作に慣れていきましょう。
Pandasには、ここで紹介した以外にもたくさんの便利な機能があります。ぜひ、さらに学習を進めて、データ分析のスキルを向上させてください!