こんにちは。前回は、Pandas DataFrameのdescribe()
メソッドを使って、データに含まれる数値やカテゴリデータの基本的な統計情報(平均値、標準偏差、最頻値など)を要約する方法を学びました。これにより、データが持つ大まかな特徴を掴むことができましたね。
さて、データ全体の概要が見えてきたところで、次に行いたくなるのが「分析に必要な部分だけを取り出す」作業です。多くの場合、手元にあるデータの全ての列が分析に必要とは限りません。むしろ、特定の情報(例えば、「社員の氏名と部署だけ」「年齢と評価スコアの関係を見たい」など)に注目して作業を進めることの方が多いでしょう。
そこで今回は、Pandas DataFrameから特定の「列」を選択して取り出す、基本的ながら非常に重要な操作方法を学びます。この記事を読み終える頃には、あなたは以下のことができるようになっているはずです。
- DataFrameから1つの列だけを選び出す方法。
- 選んだ結果が「Series(シリーズ)」という1次元のデータ形式になる場合と、「DataFrame(データフレーム)」という2次元の表形式になる場合の違いを理解する。
- DataFrameから複数の列をまとめて選び出す方法。
- 列の名前(ラベル)ではなく、列の番号(位置)を使って列を選び出す方法(
.iloc
)。 - より高度な選択方法である
.loc
を使った列選択の基本。
Excelで不要な列を非表示にする操作に似ていますが、Pandasではより柔軟で強力な方法で列を選択できます。このスキルを身につけることで、大量のデータの中から必要な情報だけを効率的に抽出し、分析を進める準備を整えることができます。
なぜ列選択が必要なのか?
本格的な解説に入る前に、なぜDataFrameから特定の列を選択する操作が重要なのか、少し考えてみましょう。主に以下のような理由が挙げられます。
- 分析対象の絞り込み: 全ての列が分析に関係するわけではありません。例えば、顧客の購買行動を分析する際に、顧客IDやメールアドレスは識別には使いますが、購買金額や購入日といった列ほど直接的な分析対象にはならないかもしれません。必要な列だけを選ぶことで、分析の焦点を明確にできます。
- データの見やすさ向上: 何十、何百もの列がある巨大なDataFrameでは、全体を表示しても情報が多すぎて混乱してしまいます。関心のある数個の列だけを表示することで、データの確認や理解が容易になります。
- 特定の列への操作: 特定の列のデータ型を変更したり、欠損値を処理したり、計算を行ったりする場合、まずその列を選択する必要があります。
- メモリ効率: 非常に大きなデータセットの場合、不要な列を削除(あるいは選択しない)ことで、コンピュータのメモリ使用量を抑えることができます。
このように、列選択はデータ分析のあらゆる場面で使われる基本的な操作なのです。
サンプルデータの準備
今回も、これまでの記事で使用してきた社員情報のサンプルデータを使います。まずは、Pandasをインポートし、DataFrame df
を準備しましょう。
import pandas as pd # サンプルデータをPythonの辞書で作る data = { '社員ID': ['S001', 'S002', 'S003', 'S004', 'S005', 'S006', 'S007'], '氏名': ['佐藤 一郎', '鈴木 花子', '高橋 健太', '田中 優子', '伊藤 次郎', '渡辺 直美', '山本 翔太'], '部署': ['営業部', '開発部', '営業部', '人事部', '開発部', '営業部', '開発部'], '年齢': [35, 28, 41, 31, 25, 38, 29], '経験年数': [10, 5, 15, 8, 2, 12, 6], '評価スコア': [4.5, 4.8, 4.2, 4.0, 4.9, 3.8, 4.6] } # 辞書データからDataFrameを作成 df = pd.DataFrame(data) # 作成したDataFrameを表示(確認用) print(df)
実行結果(再掲):
社員ID 氏名 部署 年齢 経験年数 評価スコア
0 S001 佐藤 一郎 営業部 35 10 4.5
1 S002 鈴木 花子 開発部 28 5 4.8
2 S003 高橋 健太 営業部 41 15 4.2
3 S004 田中 優子 人事部 31 8 4.0
4 S005 伊藤 次郎 開発部 25 2 4.9
5 S006 渡辺 直美 営業部 38 12 3.8
6 S007 山本 翔太 開発部 29 6 4.6
準備ができました。このdf
を使って、様々な列選択の方法を見ていきましょう。
最も基本的な列選択:[] を使う方法
DataFrameから列を選択する最もシンプルで一般的な方法は、角括弧[]
を使うことです。Excelで列ヘッダーをクリックする感覚に近いかもしれません。
単一列の選択: df['列名'] → 結果は「Series」
まず、1つの列だけを選んでみましょう。DataFrame変数の後ろに[]
をつけ、その中に選択したい列の名前(文字列)を入れます。
例えば、「氏名」列だけを選択してみます。
# '氏名'列を選択 shimei_series = df['氏名'] print(shimei_series)
実行結果:
0 佐藤 一郎
1 鈴木 花子
2 高橋 健太
3 田中 優子
4 伊藤 次郎
5 渡辺 直美
6 山本 翔太
Name: 氏名, dtype: object
元のDataFrameから「氏名」列だけが取り出されました。ここで注目してほしいのは、表示形式が元のDataFrame(表形式)とは少し違うことです。これは、単一の列を選択した場合、その結果は「Series(シリーズ)」というPandasの別のデータ形式になるためです。
Seriesとは?
Seriesは、1次元のデータを格納するためのPandasの基本的なデータ構造です。イメージとしては、インデックス(番号やラベル)が付いたリストや配列のようなものです。左側にインデックス(ここでは0
から6
)、右側にデータ(氏名)が表示されていますね。最後の行には、このSeriesの名前(元の列名である氏名
)とデータ型(dtype: object
)が表示されています。
本当にSeriesになっているか、Pythonのtype()
関数を使って確認してみましょう。
# 選択結果のデータ型を確認 print(type(shimei_series))
実行結果:
確かに、pandas.core.series.Series
クラスのオブジェクトであることが確認できました。
同様に、「年齢」列(数値データ)を選択してみましょう。
# '年齢'列を選択 age_series = df['年齢'] print(age_series)
実行結果:
0 35
1 28
2 41
3 31
4 25
5 38
6 29
Name: 年齢, dtype: int64
こちらもSeriesとして表示され、データ型がint64
(整数)であることが分かります。
単一列をDataFrameとして選択: df[['列名']] → 結果は「DataFrame」
「1つの列だけを取り出したいけれど、結果も元のDataFrameと同じ表形式(2次元)のままにしておきたい」という場合もあります。例えば、選択した列を別のDataFrameと結合したり、DataFrameを前提とする関数に渡したりする場合などです。
その場合は、列名を指定する際に角括弧[]
を二重にします。
# '部署'列をDataFrameとして選択 dept_df = df[['部署']] print(dept_df)
実行結果:
部署
0 営業部
1 開発部
2 営業部
3 人事部
4 開発部
5 営業部
6 開発部
今度は、元のDataFrameと同じように、列名(部署
)が一番上に表示され、データが表形式で表示されましたね。これは、結果がDataFrameになっていることを示します。
type()
でも確認してみましょう。
# 選択結果のデータ型を確認 print(type(dept_df))
実行結果:
期待通り、pandas.core.frame.DataFrame
クラスであることが確認できました。
なぜ[[]]
と二重にするのでしょうか? 外側の[]
はDataFrameから要素を選択するための記法ですが、内側の[]
で列名のリスト(要素が1つだけのリスト)を指定している、と考えると理解しやすいでしょう。Pandasでは、列選択時にリストで指定すると、結果がDataFrameになるというルールがあるのです。
まとめ:単一列選択の[]
と[[]]
の違い
df['列名']
: 結果はSeries(1次元データ)。df[['列名']]
: 結果はDataFrame(2次元データ、列が1つ)。
この違いは重要なので、しっかり覚えておきましょう。
複数列の選択: df[['列名1', '列名2']] → 結果は「DataFrame」
次に、複数の列を同時に選択する方法です。これも[]
を使いますが、中に選択したい列名をリストとして渡します。リストは['要素1', '要素2', ...]
のように、複数の要素をカンマで区切って[]
で囲んだものです。
例えば、「氏名」列と「評価スコア」列を選択してみましょう。
# '氏名'列と'評価スコア'列を選択 name_score_df = df[['氏名', '評価スコア']] print(name_score_df)
実行結果:
氏名 評価スコア
0 佐藤 一郎 4.5
1 鈴木 花子 4.8
2 高橋 健太 4.2
3 田中 優子 4.0
4 伊藤 次郎 4.9
5 渡辺 直美 3.8
6 山本 翔太 4.6
指定した2つの列だけが含まれる、新しいDataFrameが作成されました。列の順番は、リストで指定した順番になります。
もちろん、3つ以上の列を選択することも可能です。
# '社員ID', '部署', '年齢'列を選択 id_dept_age_df = df[['社員ID', '部署', '年齢']] print(id_dept_age_df)
実行結果:
社員ID 部署 年齢
0 S001 営業部 35
1 S002 開発部 28
2 S003 営業部 41
3 S004 人事部 31
4 S005 開発部 25
5 S006 営業部 38
6 S007 開発部 29
このように、[]
の中に列名のリストを渡すことで、必要な複数の列を簡単に取り出すことができます。結果は常にDataFrameになります。
より柔軟な選択方法:.loc と .iloc を使う
[]
を使った方法はシンプルで分かりやすいですが、Pandasにはより高機能で柔軟な選択方法として.loc
と.iloc
があります。これらは本来、行と列を同時に、より細かく指定するために使われますが、列選択のためだけにも利用できます。
.loc を使った列選択: ラベル(名前)で指定
.loc
は、ラベル(名前)に基づいてデータを選択するための機能です。基本的な形式はdf.loc[行ラベル, 列ラベル]
です。
列選択だけを行いたい場合は、行ラベルの部分に:
(コロン)を指定します。:
は「すべての行」を意味するスライス記法です。
単一列の選択 (.loc
):
# .locを使って'経験年数'列を選択(結果はSeries) exp_series_loc = df.loc[:, '経験年数'] print(exp_series_loc)
実行結果:
0 10
1 5
2 15
3 8
4 2
5 12
6 6
Name: 経験年数, dtype: int64
df['経験年数']
と同じ結果(Series)が得られました。df.loc[:, '経験年数']
は、「全ての行(:
)について、’経験年数’というラベルの列を選択する」という意味になります。
複数列の選択 (.loc
):
複数列を選択する場合は、列ラベルの部分に列名のリストを渡します。
# .locを使って'部署'列と'年齢'列を選択(結果はDataFrame) dept_age_df_loc = df.loc[:, ['部署', '年齢']] print(dept_age_df_loc)
実行結果:
部署 年齢
0 営業部 35
1 開発部 28
2 営業部 41
3 人事部 31
4 開発部 25
5 営業部 38
6 開発部 29
df[['部署', '年齢']]
と同じ結果(DataFrame)が得られました。
.loc
は、単に列を選択するだけなら[]
を使う方法と大差ないように見えるかもしれません。しかし、特定の行と列を組み合わせて選択する場合(例えば、「インデックスが3の行の、’氏名’と’年齢’列だけを取り出す」など)に非常に強力な機能を発揮します(行の選択については次回以降に詳しく解説します)。
.iloc を使った列選択: 位置(番号)で指定
.iloc
は、整数による位置(インデックス番号)に基づいてデータを選択するための機能です。基本的な形式はdf.iloc[行番号, 列番号]
です。.loc
がラベル名で指定するのに対し、.iloc
は0から始まる番号で指定する点が異なります。
列選択だけを行いたい場合も、行番号の部分に:
(すべての行)を指定します。
重要な注意点: .iloc
で使う行番号・列番号は、0から始まることに注意してください。一番最初の列は0
、2番目の列は1
、…となります。
単一列の選択 (.iloc
):
例えば、最初の列である「社員ID」列を選択してみましょう。列番号は0
です。
# .ilocを使って0番目の列('社員ID')を選択(結果はSeries) id_series_iloc = df.iloc[:, 0] print(id_series_iloc)
実行結果:
0 S001
1 S002
2 S003
3 S004
4 S005
5 S006
6 S007
Name: 社員ID, dtype: object
結果はSeriesになります。
複数列の選択 (.iloc
):
複数列を選択する場合は、列番号の部分に列番号のリストを渡します。例えば、2番目の列(’氏名’、列番号1
)と4番目の列(’年齢’、列番号3
)を選択してみましょう。
# .ilocを使って1番目と3番目の列('氏名', '年齢')を選択(結果はDataFrame) name_age_df_iloc = df.iloc[:, [1, 3]] print(name_age_df_iloc)
実行結果:
氏名 年齢
0 佐藤 一郎 35
1 鈴木 花子 28
2 高橋 健太 41
3 田中 優子 31
4 伊藤 次郎 25
5 渡辺 直美 38
6 山本 翔太 29
結果はDataFrameになります。
.iloc
は、列名が長かったり、特定の順番の列だけを取り出したい場合に便利です。ただし、列の順番が変わると意図しない列を選択してしまう可能性があるため、注意が必要です。
どの方法を使うべきか?(使い分けのヒント)
これまでいくつかの列選択の方法を見てきましたが、どれを使えば良いか迷うかもしれません。状況に応じた使い分けのヒントをまとめます。
- 最もシンプルで直感的:
df['列名']
(Series),df[['列名1', '列名2']]
(DataFrame)- 単に特定の列(単一または複数)を名前で選びたいだけなら、この方法が最も手軽で読みやすいでしょう。初心者の方にはまずこの方法をマスターすることをお勧めします。
- 単一列をDataFrameで保持したい場合:
df[['列名']]
- 結果をDataFrameの形式で扱いたい場合は、角括弧を二重にすることを忘れないでください。
- 行の選択と組み合わせたい、より明示的にラベル指定したい場合:
df.loc[:, '列名']
,df.loc[:, ['列名1', '列名2']]
- コードの意図をより明確にしたい場合や、行選択と組み合わせて使う場合に
.loc
は強力です。慣れてきたら積極的に使ってみましょう。
- コードの意図をより明確にしたい場合や、行選択と組み合わせて使う場合に
- 列の位置(番号)で指定したい場合:
df.iloc[:, 列番号]
,df.iloc[:, [列番号1, 列番号2]]
- 列名に関わらず、何番目の列か、という情報で選択したい場合に便利です。ただし、列の順序変更には注意が必要です。
基本的には、[]
を使う方法から始め、必要に応じて.loc
や.iloc
を使い分けるのが良いでしょう。
まとめ
今回は、Pandas DataFrameから特定の「列」を選択する様々な方法について学びました。
- 最も基本的な方法:
df['列名']
: 単一列を選択し、結果はSeries (1次元データ)。df[['列名']]
: 単一列を選択し、結果はDataFrame (2次元データ)。角括弧が二重なのがポイント。df[['列名1', '列名2']]
: 複数列を選択し、結果はDataFrame。列名のリストで指定。
- ラベル(名前)で指定する
.loc
:df.loc[:, '列名']
(Series),df.loc[:, ['列名1', ...]]
(DataFrame)。:
は全行を意味する。
- 位置(番号)で指定する
.iloc
:df.iloc[:, 列番号]
(Series),df.iloc[:, [列番号1, ...]]
(DataFrame)。列番号は0から始まる。
- SeriesとDataFrameの違い: 選択方法によって結果が1次元のSeriesになるか、2次元のDataFrameになるかが変わることを理解しました。
これらの列選択のスキルは、データ分析や前処理を行う上で頻繁に利用します。色々なパターンを試してみて、どの書き方でどのような結果が得られるのか、感覚を掴んでみてください。具体的なデータを使って、コードを実行し、その結果を目で見て確認することが上達への近道です。
次回予告
列の選択方法をマスターしたところで、次はデータの「行」に注目してみましょう。データ分析では、「特定の条件を満たすデータだけを取り出したい」という場面が非常に多くあります。例えば、「営業部の社員だけ」「年齢が30歳以上の社員だけ」「評価スコアが4.5以上の開発部社員だけ」といった具合です。
次回は、DataFrameから条件を指定して特定の「行」を選択(フィルタリング)する方法について、詳しく解説していきます。条件に基づいたデータの絞り込みができるようになると、より深い分析が可能になります。お楽しみに!