【Pandas入門 第2回】データを自在に操る!loc, iloc, ブールインデックスを使ったデータ選択・抽出術 🔪
「DataFrameから、特定の列だけを取り出すにはどうすればいい?」
「上から3行目、左から2列目の、あのデータが欲しい!」
「年齢が30歳以上で、かつ東京在住のデータだけを絞り込みたいんだけど…」
こんにちは! Pandas探検隊、隊長のPythonistaです! 前回の第1回では、Pandasの基本的なデータ構造であるSeries
とDataFrame
、そしてCSVやExcelからデータを読み書きする方法を学びましたね。これで、どんな表形式データもPythonの世界に招き入れる準備が整いました。
シリーズ第2回の今回は、読み込んだデータを「スライス&ダイス」する、つまり**自由自在に部分データを選択・抽出する**ためのテクニックを徹底的に解説します! データ分析とは、まさにこの「データの中から必要な部分を見つけ出す」ことから始まります。今回は、Pandasにおけるデータ選択の3つの主要な武器、
- ラベル名で指定する
.loc
- 行・列の番号で指定する
.iloc
- 条件に基づいてフィルタリングする ブールインデックス参照
をマスターしていきます。これらのテクニックを身につければ、巨大なデータの中からでも、あなたが必要とする情報をピンポイントで、かつ素早く取り出せるようになりますよ!
1. 準備:モジュールのインポートとサンプルDataFrameの作成
まずは、Pandasをインポートし、これからの例で使うサンプルデータフレームを作成しましょう。毎回ファイルから読み込むのは大変なので、今回はPythonの辞書から直接作成します。
import pandas as pd
import numpy as np
# サンプルデータを作成
data = {
'名前': ['佐藤', '鈴木', '高橋', '田中', '伊藤'],
'科目': ['数学', '英語', '数学', '理科', '社会'],
'点数': [85, 78, 92, 88, 76],
'評価': ['A', 'B', 'A', 'A', 'C']
}
# 's01', 's02' ... のようなカスタムインデックスを設定
student_ids = [f's0{i}' for i in range(1, 6)]
df = pd.DataFrame(data, index=student_ids)
print("--- サンプルDataFrame ---")
print(df)
実行結果:
--- サンプルDataFrame ---
名前 科目 点数 評価
s01 佐藤 数学 85 A
s02 鈴木 英語 78 B
s03 高橋 数学 92 A
s04 田中 理科 88 A
s05 伊藤 社会 76 C
このdf
というDataFrameを使って、様々なデータ選択の方法を見ていきましょう。
2. まずは基本!列の選択
特定の列のデータだけを取り出すのは、最も基本的な操作です。
2.1. 1つの列を選択する
DataFrame['列名']
のように、辞書のキーを指定する感覚で列名を書きます。結果は1次元のSeries
として返されます。
names_series = df['名前']
print("\n--- '名前'列 (Series) ---")
print(names_series)
print(f"\n型: {type(names_series)}")
実行結果:
--- '名前'列 (Series) ---
s01 佐藤
s02 鈴木
s03 高橋
s04 田中
s05 伊藤
Name: 名前, dtype: object
型: <class 'pandas.core.series.Series'>
2.2. 複数の列を選択する
複数の列を選択する場合は、列名のリストを角括弧[]
でさらに囲んで、DataFrame[['列名1', '列名2']]
のようにします。この「角括弧が2つ」というのがポイントです。結果は新しいDataFrame
として返されます。
name_and_score_df = df[['名前', '点数']]
print("\n--- '名前'列と'点数'列 (DataFrame) ---")
print(name_and_score_df)
print(f"\n型: {type(name_and_score_df)}")
実行結果:
--- '名前'列と'点数'列 (DataFrame) ---
名前 点数
s01 佐藤 85
s02 鈴木 78
s03 高橋 92
s04 田中 88
s05 伊藤 76
型: <class 'pandas.core.frame.DataFrame'>
3. 行と列を自在に選択:.loc
と .iloc
をマスターしよう!
行を選択したり、行と列を同時に指定したりするには、.loc
と.iloc
という2つの強力なアクセサ(アクセス手段)を使います。この2つの違いを理解することが、Pandasを使いこなす上で非常に重要です。
.loc[...]
: **ラベル (Label)** ベースの選択。行のインデックス名と列名を文字列で指定します。.iloc[...]
: **整数位置 (Integer Location)** ベースの選択。行番号と列番号を0から始まる整数で指定します。PythonのリストやNumPy配列のスライシングと同じ感覚です。
3.1. ラベルで選択する .loc
# --- .loc の使い方 ---
print("\n--- .locによる選択 ---")
# 1つの行を選択 (インデックス名's02')
row_s02 = df.loc['s02']
print(f"\n行 's02':\n{row_s02}")
# 複数の行を選択 (インデックス名のリスト)
rows_s01_s04 = df.loc[['s01', 's04']]
print(f"\n行 's01', 's04':\n{rows_s01_s04}")
# ラベルでスライス (注意: locのスライスは終了ラベルも含まれる!)
rows_slice = df.loc['s02':'s04']
print(f"\n行スライス 's02'から's04'まで:\n{rows_slice}")
# 行と列を同時に指定
value = df.loc['s03', '点数']
print(f"\n's03'の'点数': {value}") # 92
# 複数行・複数列を同時に指定
sub_df = df.loc[['s01', 's05'], ['名前', '評価']]
print(f"\n's01','s05'行の'名前','評価'列:\n{sub_df}")
3.2. 行・列番号で選択する .iloc
# --- .iloc の使い方 ---
print("\n--- .ilocによる選択 ---")
# 1つの行を選択 (0から数えて1番目の行)
row_1 = df.iloc[1]
print(f"\n1番目の行:\n{row_1}") # 鈴木さんのデータ
# 複数の行を選択 (行番号のリスト)
rows_0_3 = df.iloc[[0, 3]]
print(f"\n0番目と3番目の行:\n{rows_0_3}")
# 番号でスライス (Python標準と同じで、終了番号は含まれない!)
rows_slice_iloc = df.iloc[1:4] # 1, 2, 3番目の行
print(f"\n行スライス 1から4の手前まで:\n{rows_slice_iloc}")
# 行と列を同時に指定
value_iloc = df.iloc[2, 2] # 2行目, 2列目
print(f"\n2行目, 2列目の値: {value_iloc}") # 92
# 複数行・複数列を同時に指定
sub_df_iloc = df.iloc[0:3, 0:2] # 0-2行, 0-1列
print(f"\n0-2行, 0-1列:\n{sub_df_iloc}")
まとめ: loc
vs iloc
loc
: ラベル名で指定。スライスは**終了値を含む**。iloc
: 整数位置で指定。スライスは**終了値を含まない**(Python標準と同じ)。
この違いをしっかり理解することが、Pandas操作のミスを減らす鍵です!
4. 条件でフィルタリング:ブールインデックス参照
データ分析の現場で最もよく使われるのが、特定の条件に合うデータだけを抽出する「フィルタリング」です。これは、NumPyでも学んだブールインデックス参照というテクニックを使います。
4.1. 基本的な条件でのフィルタリング
まず、df['列名'] > 値
のような比較演算を行うと、各行が条件を満たすかどうかがTrue
/False
のSeries
として返されます。このブールSeries
を、そのままDataFrame
のインデックスとして使うことで、True
の行だけを抽出できます。
# '点数'が80点より大きい行だけを抽出
high_scores_condition = df['点数'] > 80
print("\n--- 点数 > 80 の条件 (ブールSeries) ---")
print(high_scores_condition)
print("\n--- 点数が80点より大きいデータ ---")
high_scores_df = df[high_scores_condition]
print(high_scores_df)
# 1行で書くのが一般的
math_students_df = df[df['科目'] == '数学']
print("\n--- 科目が数学のデータ ---")
print(math_students_df)
4.2. 複数の条件を組み合わせる
複数の条件を組み合わせるには、論理演算子&
(AND) と |
(OR) を使います。
非常に重要な注意点:各条件式は、必ず個別の丸括弧 ()
で囲む必要があります!
# '科目'が数学で、かつ'点数'が90点以上のデータ
math_and_high_score_df = df[(df['科目'] == '数学') & (df['点数'] >= 90)]
print("\n--- 数学で90点以上 ---")
print(math_and_high_score_df)
# '評価'が'A'または'C'のデータ
evaluation_a_or_c_df = df[(df['評価'] == 'A') | (df['評価'] == 'C')]
print("\n--- 評価がAまたはC ---")
print(evaluation_a_or_c_df)
4.3. .isin()
メソッドと否定(~
)
複数のOR条件は、.isin()
メソッドを使うと、より簡潔に書けます。また、条件を否定するには~
演算子を使います。
# '科目'が'数学'または'理科'のデータ
subjects_to_find = ['数学', '理科']
math_or_science_df = df[df['科目'].isin(subjects_to_find)]
print("\n--- isinで数学または理科 ---")
print(math_or_science_df)
# '科目'が'数学'ではないデータ
not_math_df = df[~df['科目'].isin(['数学'])]
print("\n--- 数学ではないデータ ---")
print(not_math_df)
まとめ:これであなたもデータ選択の達人!
今回は、Pandas入門シリーズの第2回として、DataFrameから必要なデータを自由自在に取り出すための重要なテクニックを学びました。
- 列の選択:
df['列名']
(Series)やdf[['列名1', '列名2']]
(DataFrame)。 .loc[]
: ラベル名を使って行と列を選択する(スライスは終了値も含む)。.iloc[]
: 整数位置を使って行と列を選択する(スライスは終了値を含まない)。- ブールインデックス参照:
df[条件式]
の形で、条件に合うデータをフィルタリングする。&
(AND) と|
(OR) で複数条件もOK。
これらのデータ選択・抽出スキルは、あらゆるデータ分析作業の基礎となる、いわば「下ごしらえ」の技術です。これができなければ、データの集計も、可視化も、機械学習も始まりません。
さて、データの中から欲しいものを自在に取り出せるようになったあなた。しかし、もしそのデータに「欠けている部分(欠損値)」があったり、「間違ったデータ型」で保存されていたり、「重複したデータ」が混じっていたらどうしますか?
次回、第3回では、現実世界の「汚れた」データを綺麗にするための「データクリーニングと前処理」に挑戦します!欠損値(NaN)の扱い、データ型の変換、重複データの処理といった、データ分析の現場で必須となるスキルを学んでいきましょう。お楽しみに!
コメント
コメントを投稿