Python
 Computer >> コンピューター >  >> プログラミング >> Python

Python Pandasの辞書式スライシングでデータのサブセットを抽出する方法を徹底解説

はじめに

Pandasには、インデックス位置(番号)またはインデックスラベル(文字列)を使ってデータのサブセットを選択できる、2つの選択機能が備わっています。本記事では、その中でも「辞書式スライシング(lexicographical slicing)」を使ってデータのサブセットを抽出する方法を詳しく解説します。

インターネット上には豊富なデータセットが公開されています。例えばkaggle.comで「movies dataset」と検索すると映画関連のデータセットが見つかります。本記事では、Kaggleの映画データセットを使用して説明していきます。

実装手順

1. データセットの読み込み

まず、この例に必要なカラムだけを指定して、映画データセットを読み込みます。ここでは「title」をインデックスとして設定しています。

import pandas as pd
import numpy as np
movies = pd.read_csv("https://raw.githubusercontent.com/sasankac/TestDataSet/master/movies_data.csv",index_col="title",
usecols=["title","budget","vote_average","vote_count"])
movies.sample(n=5)

読み込んだデータは以下のようになります。

titlebudgetvote_averagevote_count
Little Voice06.661
Grown Ups 2800000005.81155
The Best Years of Our Lives21000007.6143
Tusk28000005.1366
Operation Chromite05.829

2. インデックスをソートする重要性

特にインデックスが文字列で構成されている場合は、必ずインデックスをソートしておくことをおすすめします。大規模なデータセットを扱う場合、インデックスがソートされているかどうかで処理速度に大きな差が出ることに気づくでしょう。

インデックスをソートしないとどうなる?

もちろんコード自体は動きますが、インデックスラベルがソートされていない場合、Pandasはクエリに一致するラベルを見つけるために、すべてのラベルを1つずつ順番に走査しなければなりません。索引ページがないOxford辞典を想像してみてください。目的の単語を探すのに最初からページをめくるしかありませんよね。インデックスがソートされていれば、目的のラベルへ素早くジャンプできます。Pandasも同じ仕組みです。

まず、現在のインデックスがソートされているかどうか確認してみましょう。

# インデックスがソートされているか確認
movies.index.is_monotonic

False

3. ソートされていない状態でのスライシングはエラーになる

結果はFalse。明らかにインデックスはソートされていません。この状態で、「A」で始まる映画タイトルを選択してみます。SQLで書くと次のようなイメージです。

select * from movies where title like 'A%'

Pandasでは以下のように記述します。

movies.loc["Aa":"Bb"]

しかし、このコードを実行するとエラーが発生します。

ValueError: index must be monotonic increasing or decreasing
KeyError: 'Aa'

エラーメッセージにある通り、「index must be monotonic increasing or decreasing(インデックスは単調増加または単調減少である必要があります)」という例外が発生します。これが辞書式スライシングにはソート済みインデックスが必須である理由です。

4. インデックスを昇順にソートする

そこで、インデックスを昇順にソートしてから、同じコマンドを実行します。これにより、ソートの恩恵を受けた高速な辞書式スライシングが可能になります。

movies = movies.sort_index()
movies.index.is_monotonic

True

5. 辞書式スライシングの実行

これでデータの準備が整いました。「A」から「B」で始まるすべての映画タイトルを選択してみましょう。

movies.loc["A":"B"]

実行結果は以下の通りです。

titlebudgetvote_averagevote_count
Abandon250000004.645
Abandoned05.827
Abduction350000005.6961
Aberdeen07.06
About Last Night125000006.0210
............
Battle for the Planet of the Apes17000005.5215
Battle of the Year200000005.988
Battle: Los Angeles700000005.51448
Battlefield Earth440000003.0255
Battleship2090000005.52114

一方、降順にソートされたデータに対して「Aa」〜「Bb」のように昇順の範囲を指定すると、該当するデータが存在しないため空のDataFrameが返されます。

titlebudgetvote_averagevote_count
Æon Flux620000005.4703
xXx: State of the Union600000004.7549
xXx700000005.81424
eXistenZ150000006.7475
[REC]²56000006.4489

これは当然の結果です。データが逆順(降順)にソートされているためです。そこで、指定する文字の順序を逆にして再度実行してみましょう。

movies.loc["B":"A"]

今度は正しくデータが抽出されました。

titlebudgetvote_averagevote_count
B-Girl05.57
Ayurveda: Art of Being3000005.53
Away We Go170000006.7189
Awake860000006.3395
Avengers: Age of Ultron2800000007.36767
............
About Last Night125000006.0210
Aberdeen07.06
Abduction350000005.6961
Abandoned05.827
Abandon250000004.645

まとめ

Pandasの辞書式スライシングを使えば、SQLのLIKE 'A%'のような前方一致検索を直感的に行えます。ただし重要なポイントとして、スライシングを行う前にインデックスを必ずソートしておく必要があります。ソートされていないインデックスに対してスライシングを実行するとエラーが発生し、また降順ソートの場合は開始・終了の指定順序にも注意が必要です。sort_index()is_monotonicを活用して、効率的なデータ抽出を実現しましょう。

  1. 【Python・Pandas】Indexがカテゴリデータを保持しているかどうかを確認する方法

    PandasのIndex(インデックス)がカテゴリ型(category)のデータを保持しているかどうかを確認するには、index.is_categorical()メソッドを使用します。この記事では、実際のコード例と出力結果をもとに、具体的な手順をわかりやすく解説します。 事前準備:ライブラリのインポート まず、必要なライブラリであるPandasをインポートします。 import pandas as pd カテゴリ型のIndexを作成する astype()メソッドを使うと、既存のIndexのデータ型を「category」に変換できます。ここでは、文字列のリストからカテゴリ型のPandasインデッ

  2. 【Python】Pandas DataFrameからサブセット(列の一部)を選択する方法

    Pandas DataFrameのサブセット選択とは? Pandasでは、DataFrameから必要な列や行だけを取り出す操作を「サブセットの選択」と呼びます。大きなデータセットから目的のデータだけを抽出できれば、分析や前処理の効率が大幅に向上します。 この記事では、CSVファイルを読み込んだDataFrameから、1つの列、および複数の列を選択する基本的な方法を解説します。 使用するCSVファイルの内容 今回使用する「SalesData.csv」は、Microsoft Excelで開くと以下のような内容になっています。 CSVファイルからDataFrameを作成する まず、pd.rea