pandas DataFrameでの条件抽出


すぐ忘れてしまいそうなので、忘備録及び

にそこまで載っていなかったので。

レファレンス:

困ったら、ここで調べるととりあえずは載っている。

で実施

元のデータのダウンロード

data_dl.ipynb
import pandas as pd

url_train = "http://archive.ics.uci.edu/ml/machine-learning-databases/adult/adult.data"
url_test = "http://archive.ics.uci.edu/ml/machine-learning-databases/adult/adult.test"


cols= ["age", "workclass", "fnlwgt", "education",
"educationnum", "maritalstatus", "occupation",
"relationship", "race", "sex", "capitalgain",
"capitalloss", "hoursperweek", "nativecountry","incomelevel"]

df_train = pd.read_csv(url_train, names=cols)
df_test = pd.read_csv(url_test, names=cols, skiprows=1)

1994 US Census Income Dataを使用

read_csv()が便利すぎ

nominal(名義尺度)な列の確認

df_nominal.ipynb
df_nominal=df_train.describe(include='all').head(4).dropna(axis=1)
df_nominal
index workclass education maritalstatus occupation relationship race sex nativecountry incomelevel
count 32561 32561 32561 32561 32561 32561 32561 32561 32561
unque 9 16 7 15 6 5 2 42 2
top Private HS-grad Married-civ-spouse Prof-specialty Husband White Male United-States <=50K
freq 22696 10501 14976 4140 13193 27816 21790 29170 24720

describe()include='all'で基本統計量を出すと、数値の列はuniqueの行がNaNになるので、それをaxis=1で列を指定してdropna()で落としている。

binary(2値)な列の抽出

df_binary.ipynb
df_binary=df_nominal.loc[:, (df_nominal.loc['count'] == 32561) & (df_nominal.loc['unique']==2)].T.drop(['unique','top'], axis=1)
df_binary
index count freq
sex 32561 21790
incomelevel 32561 24720

調べるのに結構苦労した、2つの条件による抽出

(df_nominal.loc['count'] == 32561) & (df_nominal.loc['unique']==2)

()で囲うのと&|を使用しなければいけない。

loc[行,列]の指定なので、[:,条件式]としている。

新な列の作成と条件による値の変更

balanced.ipynb
df_binary=df_binary.assign(balanced=lambda df: df["freq"] / df["count"])
df_binary
#
# いったん数値列を作成
#
df_binary["balanced"]=df_binary["balanced"].apply(lambda x: "balanced" if x > 0.4 and x < 0.6 else "imbalanced")
df_binary
index count freq balanced
sex 32561 21790 0.669205
incomelevel 32561 24720 0.75919
index count freq balanced
sex 32561 21790 imbalanced
incomelevel 32561 24720 imbalanced

assign()で新しい列を作成。 lambdaの引数はこの場合DataFrame(らしい・・・)

そのあとapply()で条件により値を文字列に変更。
いろいろ試したところ、Seriesでやらないとうまくいかなかった。

ここではandが使えている。0.4 < x < 0.6とやりたかったけど、なんかうまくいかなかった。

まとめ

pandasDataFrame内での条件判定はandorではなく&|を使用するところや、列の値によって条件判定して値を変えるのはそれなりに使うと思います。