このページで解説している内容は、以下の YouTube 動画の解説で見ることができます。

【Python入門】データフレームの列や行の要素を取得する

データフレームの列や行の要素を取得する

 大量の表形式データを扱う際、特定の列や行、さらに条件によるフィルタリングを柔軟に実行できると非常に便利です。PandasのDataFrame(データフレーム)は、こうした操作を簡潔なコードで行えるように設計されています。
 ここでは、Pandasを使って作成したデータフレームから、列・行・要素を抽出する各種方法や、条件によるフィルタリング、新しい列の追加と不要列の削除、そしてCSVへの出力の手順を一通り解説します。

プログラムのダウンロード

 「ダウンロード」から、JupyterLab で実行できるサンプルプログラムがダウンロードできます。ファイルは、ESET Endpoint Securityでウイルスチェックをしておりますが、ダウンロードとプログラムの実行は自己責任でお願いいたします。


1.サンプルデータの準備

 今回の例では、physics, biology, chemistryという3科目のスコアをまとめたファイル「science_scores.csv」(全200行)を用意します。先頭行には列名が定義されており、以降の行に実際のスコアが並んでいる想定です。たとえば以下のような構造です(実際には200行ぶん用意してください)。

Physics,Biology,Chemistry
65,70,85
72,63,90
81,59,74
93,88,66
... (合計200行)

サンプルデータ「science_scores.csv」の作成

 下記のコードセルをJupyterLabで実行すると、現在のディレクトリにscience_scores.csvというファイルが生成されます。ファイルには、先頭行(列名)を含めて合計201行が書き込まれ、各行に物理(Physics)、生物(Biology)、化学(Chemistry)のスコアがランダムに格納されます。

import random

def create_science_csv(filename="science_scores.csv", rows=200):
    """
    指定したファイル名で、
    Physics, Biology, Chemistry の3科目のスコアをランダムに200行分出力する関数。
    """
    with open(filename, "w", encoding="utf-8") as f:
        # 先頭行に列名を書き込む
        f.write("Physics,Biology,Chemistry\n")
        
        # rows行分のスコアを生成
        for _ in range(rows):
            physics = random.randint(40, 100)   # 物理: 40〜100の整数
            biology = random.randint(40, 100)   # 生物: 40〜100の整数
            chemistry = random.randint(40, 100) # 化学: 40〜100の整数
            f.write(f"{physics},{biology},{chemistry}\n")
    
    print(f"ファイル '{filename}' が作成されました({rows}行のデータ)。")

# 実行例
create_science_csv("science_scores.csv", rows=200)

2.Pandasを使ってCSVを読み込む

 まずはPandasライブラリをインポートし、CSVファイルをDataFrameとして読み込みます。文字コードがUTF-8以外の場合は、encoding引数を変更してください。

import pandas as pd

# CSVファイルを読み込み (カレントディレクトリに "science_scores.csv" がある想定)
df = pd.read_csv("science_scores.csv", encoding="utf_8")

# DataFrameの内容を確認
df

実行結果

  • pd.read_csv("science_scores.csv", encoding="utf_8")
    CSVファイルをDataFrameに変換します。列名はファイルの先頭行から取得。
  • 出力結果として行番号(0開始)と列名("Physics","Biology","Chemistry")が表示されるはずです。

3.列を指定して取得する

3.1.単一の列を取り出す

 DataFrameの列は「辞書」のようにキーに列名を指定するか、ドット記法(属性として列名を指定)で取得できます。ドット記法は列名に空白などがない場合に有効です。

# 列名をキーで指定
physics_col = df["Physics"]
print(physics_col)

実行結果

0      58
1      76
2      72
3      96
4      49
       ..
195    53
196    89
197    53
198    75
199    91
Name: Physics, Length: 200, dtype: int64
  • df["Physics"] : 指定した列名の列(Seriesオブジェクト)を取り出す。
  • 出力には、インデックス(行番号)・値・列名などが表示されます。

3.2.複数列をまとめて取得

# 例: 物理(Physics)と化学(Chemistry)を同時に取り出す
phys_chem = df[["Physics", "Chemistry"]]
print(phys_chem)

df[["Physics", "Chemistry"]] : リスト内に複数列名を指定することで複数列をDataFrame形式で取得。

実行結果

     Physics  Chemistry
0         58         76
1         76        100
2         72         97
3         96         50
4         49         41
..       ...        ...
195       53         65
196       89         45
197       53         40
198       75         65
199       91         91

[200 rows x 2 columns]

4.行をスライスで指定して取得する

 PythonのリストやNumPy配列と同様、行番号は0から始まり、df[start:end]start行目からend-1行目までを取り出せます。

# 例: 行番号10〜14(14は含まれず)を抜き出す
slice_data = df[10:14]
print(slice_data)

実行結果

    Physics  Biology  Chemistry
10       43       48         92
11       88       50         68
12       55       52         59
13       95       87         45
  • df[10:14] : 行番号10,11,12,13が抽出される。
  • スライスにステップを指定することもできます。df[0:10:2]とすれば、行番号0,2,4,6,8が得られます。

5.行と列を同時に指定して取得する

 たとえば、「物理と化学」だけを行番号5〜9で取り出したいという場合、以下の二通りの方法があります。

5.1.「列 → 行」の順で指定

sub_df1 = df[["Physics","Chemistry"]][5:10]
print(sub_df1)

実行結果

   Physics  Chemistry
5       51         45
6       85         46
7       56         75
8       94         61
9       47         93

最初に列を絞り込み、その結果から行スライスを指定。

5.2.「行 → 列」の順で指定

sub_df2 = df[5:10][["Physics","Chemistry"]]
print(sub_df2)

実行結果

   Physics  Chemistry
5       51         45
6       85         46
7       56         75
8       94         61
9       47         93
  • 最初に行を絞り込み、そのあと列を絞り込む。
  • 結果は同じになります。

6.条件に基づく要素の取得(ブールインデックス)

DataFrameでも、NumPy配列と同じようにブールインデックスを使ったフィルタリングが可能です。

6.1.単一の条件

# 例: Chemistryが90以上の行だけ
high_chem = df[df["Chemistry"] >= 90]
print(high_chem)

実行結果

     Physics  Biology  Chemistry
1         76       71        100
2         72      100         97
9         47       98         93
(省略)
187       52       84         91
191       54       49         93
199       91       58         91
  • df["Chemistry"] >= 90 は真偽値(True/False)のSeriesを返す。
  • df[...] の部分に真偽値を指定することで、Trueの行のみ抽出。

6.2.複数条件の組み合わせ

# 例: Physicsが80以上 AND Biologyが80以上
df_both = df[(df["Physics"] >= 80) & (df["Biology"] >= 80)]
print(df_both)

実行結果

     Physics  Biology  Chemistry
13        95       87         45
18        83       89         75
20        91       96         48
(省略)
179       87       99         42
182       96       84         91
196       89       87         45
  • &(AND), |(OR), ~(NOT)などを組み合わせ可能。
  • 比較演算子と論理演算子を併用する際は、式を括弧で囲む必要がある。

6.3.queryメソッド

# 例: PhysicsまたはChemistryが100の行を抽出
df_query = df.query("Physics == 100 or Chemistry == 100")
print(df_query)

実行結果

     Physics  Biology  Chemistry
1         76       71        100
34       100       82         72
84        53       48        100
139       60       47        100
173       46       97        100
  • df.query("式") : 文字列で与えられた式に合致する行を取り出す。
  • 文字列内で列名を直接参照できるため、複雑な条件を一行で書きやすい。

7.特定の要素だけを取り出す(ilocやloc)

 行と列を両方数値インデックスで指定する場合は、ilocを使うと便利です。一方、列名や行名(ラベル)を使って位置を指定する場合はlocを使います。

# iloc[row_index, col_index]
# 例: 行番号3, 列番号2 の要素を取得
val = df.iloc[3, 2]
print(val)

実行結果

50
  • df.iloc[3, 2] : 4行目の3列目の要素。
  • 行名や列名が文字列の場合はlocを使う。

8.新しい列を追加・不要列を削除

8.1.新しい列を追加

複数の列を足し合わせるなどの演算結果を新しい列として追加する。

# 例: 全科目(Physics, Biology, Chemistry)の合計を "Total" 列に追加
df["Total"] = df["Physics"] + df["Biology"] + df["Chemistry"]
print(df.head(5))

実行結果

   Physics  Biology  Chemistry  Total
0       58       98         76    232
1       76       71        100    247
2       72      100         97    269
3       96       59         50    205
4       49       62         41    152
  • df["Total"] = ... : DataFrameに"Total"列が新規追加される。
  • 列方向(axis=1)の合計はdf.sum(axis=1)でも計算可能。

8.2.不要列を削除

# 例: "Total"列を削除
del df["Total"]
print(df.columns)

実行結果

Index(['Physics', 'Biology', 'Chemistry'], dtype='object')

del df["列名"] : 指定した列をDataFrameから完全に消去。

9.CSVファイルに出力する

加工したDataFrameを保存するには、to_csv()メソッドを使います。行番号が不要ならindex=Falseを指定。

# 例: dfを "science_output.csv" に保存
df.to_csv("science_output.csv", index=False)

df.to_csv("ファイル名") : CSV形式で書き出し。デフォルトでは行番号が付加される。

10.サンプルプログラム

 以下のコードセルをJupyterLabで実行すると、一連の操作(読み込み、列・行・条件の抽出、新規列の追加、ファイル保存など)を一度に確認できます。CSVファイル名は適宜修正してください。

import pandas as pd

def process_science_scores(csv_file="science_scores.csv"):
    """
    指定されたCSVファイルを読み込み、各種列・行の取り出し、
    条件抽出、新しい列の追加、不要列の削除を行うサンプル。
    結果をCSVファイルに再度出力。
    """
    # データ読み込み
    score = pd.read_csv(csv_file, encoding="utf_8")
    
    print("=== 先頭5行 ===")
    print(score.head(5), "\n")
    
    # 列の抽出 (物理と化学)
    print("=== PhysicsとChemistry列のみ先頭5行 ===")
    print(score[["Physics","Chemistry"]].head(5), "\n")
    
    # 行の抽出 (行番号10~14)
    print("=== 行番号10~13を表示 ===")
    print(score[10:14], "\n")
    
    # 条件抽出 (Chemistryが90以上)
    high_chem = score[score["Chemistry"] >= 90]
    print("=== Chemistryが90以上の行 ===")
    print(high_chem.head(5), "\n")
    
    # 新しい列: 3科目合計
    score["Total"] = score["Physics"] + score["Biology"] + score["Chemistry"]
    print("=== 'Total'列を追加後の先頭5行 ===")
    print(score.head(5), "\n")
    
    # 不要な列を削除 (例: "Biology"を削除してみる)
    del score["Biology"]
    print("=== 'Biology'列を削除した先頭5行 ===")
    print(score.head(5), "\n")
    
    # CSVへ出力
    out_file = "science_scores_output.csv"
    score.to_csv(out_file, index=False)
    print(f"=== 出力完了: {out_file} ===")

# 実行例
process_science_scores("science_scores.csv")

実行結果

=== 先頭5行 ===
   Physics  Biology  Chemistry
0       58       98         76
1       76       71        100
2       72      100         97
3       96       59         50
4       49       62         41 

=== PhysicsとChemistry列のみ先頭5行 ===
   Physics  Chemistry
0       58         76
1       76        100
2       72         97
3       96         50
4       49         41 

=== 行番号10~13を表示 ===
    Physics  Biology  Chemistry
10       43       48         92
11       88       50         68
12       55       52         59
13       95       87         45 

=== Chemistryが90以上の行 ===
    Physics  Biology  Chemistry
1        76       71        100
2        72      100         97
9        47       98         93
10       43       48         92
14       45      100         91 

=== 'Total'列を追加後の先頭5行 ===
   Physics  Biology  Chemistry  Total
0       58       98         76    232
1       76       71        100    247
2       72      100         97    269
3       96       59         50    205
4       49       62         41    152 

=== 'Biology'列を削除した先頭5行 ===
   Physics  Chemistry  Total
0       58         76    232
1       76        100    247
2       72         97    269
3       96         50    205
4       49         41    152 

=== 出力完了: science_scores_output.csv ===

解説

  1. pd.read_csv(csv_file, encoding="utf_8")
    CSVファイルを読み込み、DataFrameとして返す。
  2. 列抽出
    score[["Physics","Chemistry"]]のようにリストで指定することで複数列を取得。
  3. 行抽出
    score[10:14]で10〜13行をスライスで切り出し。
  4. 条件抽出
    score[score["Chemistry"] >= 90]でケミストリースコアが90以上の行のみ取得。
  5. 新しい列の追加
    score["Total"] = ...で加算結果を"Total"列に格納。
  6. 列の削除
    del score["Biology"]で「Biology」列を削除。
  7. CSVへの保存
    score.to_csv("science_scores_output.csv", index=False)で行番号を付けずにファイル出力。

まとめ

 PandasのDataFrameは、列名をキーにした辞書のようなインターフェースと、スライスによる行指定、ブールインデックスによる条件抽出など、多様なアクセス手法を提供しています。これにより、大規模な表形式データの前処理や分析を非常に効率よく行うことができます。新しい列を追加したり不要な列を削除する操作も簡単で、さらに加工後のデータをまたCSVへ書き出すなど、機械学習やデータ解析のワークフローで不可欠な機能がスムーズに実装可能です。Pandasの各種メソッドを組み合わせて、より高度なデータ処理や集計、グルーピングなどを試してみるとよいでしょう。