pandasのSeriesにbetweenという便利なメソッドが定義されていたのでその紹介です。
これを使わなくても何も難しいことのない話なのですが、コードが少し短くなってすっきりするので気に入っています。
ドキュメント: pandas.Series.between
これは、Seriesに対して、最小値、最大値を渡すと、
Seriesの各値に対して、その値が最小値と最大値の範囲に入っていればTrue, 入っていなければFalseを返すメソッドです。
これを使って、DataFrameの列の絞り込みができます。
試すために、いつものirisでDataFrameを作っておきます。
import pandas as pd
from sklearn.datasets import load_iris
# アヤメのデータを読み込んでDataFrameに整形
iris = load_iris()
columns = [c.replace(" (cm)", "") for c in iris.feature_names]
df = pd.DataFrame(iris.data, columns=columns)
df["target"] = [iris.target_names[t] for t in iris.target]
print(df.head())
"""
sepal length sepal width petal length petal width target
0 5.1 3.5 1.4 0.2 setosa
1 4.9 3.0 1.4 0.2 setosa
2 4.7 3.2 1.3 0.2 setosa
3 4.6 3.1 1.5 0.2 setosa
4 5.0 3.6 1.4 0.2 setosa
"""
このようなデータから、たとえば、”petal length” が 4.0以上4.5以下の行を抽出したいとします。
それを単純に書くとこうなります。
df[(df["petal length"] >= 4.0) & (df["petal length"] <= 4.5)]
DataFrameの変数名を3回も書かないといけないですし、ちょっと冗長ですね。
これが betweenを使うと、次のように書けます。
df[df["petal length"].between(4.0, 4.5)]
少しだけすっきりしました。
実際に絞り込めているのを確認しておきましょう。 describe()メソッドを使って、その中から最小値と最大値だけ取ってみます。
print(df[df["petal length"].between(4.0, 4.5)].describe().loc[["min", "max"]])
"""
sepal length sepal width petal length petal width
min 4.9 2.2 4.0 1.0
max 6.7 3.4 4.5 1.7
"""
注意ないといけないのは、選択されるのは、
1つ目の引数 $<=$ 指定列の値 $<=$ 2つ目の引数
と言うふうに左右両方とも等号が入った閉区間の値であることです。
3つ目の引数、 inclusive にFalse を指定すると等号を含まなくなるのですが、これは最大最小両方とも統合を含まず、
1つ目の引数 $<$ 指定列の値 $<$ 2つ目の引数
の区間を取得するようになります。
print(df[df["petal length"].between(4.0, 4.5, False)].describe().loc[["min", "max"]])
"""
sepal length sepal width petal length petal width
min 5.5 2.3 4.1 1.0
max 6.7 3.1 4.4 1.5
"""
一番頻繁に使う、x以上、y未満、と言う形式の指定ができないのが短所ですね。
以上未満で指定したい場合は、下記のようにqueryメソッドなど別の方法も検討しましょう。
df.query("4.0 <= `petal length` < 4.5")