質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

87.37%

データフレームから条件に合うデータを抽出する

解決済

回答 1

投稿

  • 評価
  • クリップ 0
  • VIEW 540

前提・実現したいこと

データフレームの各列毎に、四分位範囲の観点からデータ抽出の下限値および上限値を算出し、その範囲を満たすデータを抽出したい。

例えば下記のirisのデータを用いて、

from sklearn.datasets import load_iris
import pandas as pd

iris = load_iris()

df = pd.DataFrame(iris.data, columns=iris.feature_names)
df.describe().round(1)

# データの抽出条件を求める(describe()で得られる25%タイル値と75%タイル値を利用する)
# 抽出条件は、下限値=第1四分位値 - 1.5 x 四分位範囲、上限値=第3四分位値 + 1.5 x 四分位範囲
cols = df.columns
iris_25 = []
iris_75 = []
for col in cols:
    iris_25.append(df[col].describe()[4]) # 第1四分位値
    iris_75.append(df[col].describe()[6]) # 第3四分位値

# 四分位範囲を求め、リストに格納
iris_IQR_list =  []
for i in range(4):
    iris_IQR_list.append(iris_75[i] - iris_25[i])

# 下限値、上限値の算出
iris_lower_Q = []
iris_higher_Q = []
for i in range(4):
    iris_lower_Q.append(iris_25[i] - 1.5*iris_IQR_list[i])
    iris_higher_Q.append(iris_75[i] + 1.5*iris_IQR_list[i])

# 上記で算出した下限値、上限値の間に入る値を元のデータフレームから抽出する
for i, col in zip(range(4), cols):
    (iris_lower_Q[i] < df[col]) & (df[col] < iris_higher_Q[i])


最終行のコードから、条件を満たすbool型が得られたのですが、これをどうやって元のデータフレームに適用すればいいのか(どうやったら抽出できるのか)分かりません。
どうぞよろしくお願いいたします。

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 1

checkベストアンサー

0

以下のようにすれば、列ごとに計算しなくても[Q1 - 1.5 * IQR, Q3 + 1.5 * IQR] の範囲の値をまとめて抽出できます。
範囲外の値は NaN になります。

from sklearn.datasets import load_iris
import pandas as pd

iris = load_iris()
df = pd.DataFrame(iris.data, columns=iris.feature_names)

q1 = df.quantile(q=0.25)
q3 = df.quantile(q=0.75)
iqr = q3 - q1

# 抽出する
df2 = df[(q1 - 1.5 * iqr <= df) & (df <= q3 + 1.5 * iqr)]

サンプル

df = pd.DataFrame({"A": [1, 2, 3, 4], "B": [2, 3, 4, 5]})
lower = pd.Series({"A": 2, "B": 3})
upper = pd.Series({"A": 3, "B": 4})

# 抽出する
df2 = df[(lower <= df) & (df <= upper)]
print(df2)
#      A    B
# 0  NaN  NaN
# 1  2.0  3.0
# 2  3.0  4.0
# 3  NaN  NaN

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2020/08/29 00:59

    早速のレスポンスありがとうございます。
    そして、こんなにも簡単にできてしまうとは、、、
    非常に勉強になりましたし、助かりました。
    どうもありがとうございました!

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 87.37%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る