Kaggleで使えるpandasテクニック集
PythonでKaggleなどのデータ分析を行う際、pandasでゴリゴリ作業をすることが多いかと思います。
最近知って「めっちゃ便利やん!」ってなったものをまとめておきたいと思います。 全部の関数にドキュメントへのリンクを付けたので参考にしてください。
今回も検証にはTitanicのデータセットを用います。また、文中でのdf.hoge()
はpandasのDataFrameのメソッドであることを、pd.hoge()
はpandasの関数であることを表します。
df = read_csv('input/train.csv', index_col=0) print(df.shape) df.head()
最低限押さえておきたいやつら
まずはここから。
よく使うやつら。詳しい解説は省略するので、ドキュメントのリンク先を見てください。
関数 | 内容 | リンク |
---|---|---|
df.describe() |
最大最小、平均など基本統計量の表示 | doc |
df.head() df.tail() |
先頭/末尾のn行を取る | doc |
df.values |
numpyのarrayで取り出す | doc |
df.isnull() df.notnull() |
NaNかどうか判定 | doc |
df.apply() df.map() |
各行に処理をする | doc |
series.plot.hoge() |
プロットいろいろ | doc |
複雑な条件に該当する行を取る
df.query()
doc
SQL-likeなクエリ文を利用することで該当する行を取得します。
Pclassが1で、30歳以上の人を表示してみます。
new = df.query("Pclass==1 and Age >= 30") print(new.shape) new.head()
クエリ文の中では列名がそのまま変数として使えるほか、変数名の先頭に@
をつけることで外部の変数も利用することができます。
列名の一部で列を選ぶ
df.filter()
doc
regex='hoge'
で正規表現も使えます。列名のネーミングが統一されているDataFrameに対しては絶大な力を発揮します。
自分で列名をつけるときには適切な接頭辞・接尾辞などを使って良いネーミングをするよう心がけておきましょう。
列名がP
で始まる列を取得してみます。(なんじゃそりゃ)
new = df.filter(regex='^P') print(new.shape) new.head()
特定の型の列だけを取ってくる
df.select_dtypes()
doc
Kaggleだと変数がintだったりfloatだったりbooleanだったり文字列だったりするので、文字列だけ取って来るときなどに使えます。
文字列はDataFrame内ではobject
という型で扱われています。
整数・小数・真偽値以外はすべてobject
になってしまいますが、Kaggleのようにcsvから読み込む場合はobject
なら文字列と思って良いでしょう。
new = df.select_dtypes(['object']) print(new.shape) new.head()
文字列の列だけ取れていることが分かります。
文字列の列名を取得する場合はこんな感じでしょうか。
# 愚直な方法 cat_cols = [f for f in df.columns if df[f].dtype == 'object'] # select_dtypesを使った場合 cat_cols = df.select_dtypes(['object']).columns
exclude
を利用して、特定の型を除くこともできます。
new = df.select_dtypes(exclude=np.float) print(new.shape) new.head()
分類ごとに数える・集計する
df.groupby()['hoge'].value_counts().unstack()
は行にする変数Aと列にする変数Bを選び、Aでグループを作ってBの種類ごとに集計することができます。
Pclass(船室等級)でグループを作り、Survived
の値を種類ごとに集計してみます。
df.groupby('Pclass')['Survived'].value_counts().unstack()
df.pivot_table()
はより一般化し、2つの変数A, Bに着目して別の変数Cを集計することができます。
性別とPclass(船室等級)について、生存率を集計してみましょう。
df.pivot_table(index='Sex', columns='Pclass', values='Survived', aggfunc=np.mean)
……これは悲惨ですね。1等2等船室の女性は90%以上生き残るのに、2等3等船室の男性は10%そこそこしか生き残らないという。
プログレスバーを表示する
各行に処理を行いたい場合はdf.apply()
やdf.map()
を使いますが、tqdm
というライブラリを使うことでプログレスバーを表示することができます。
名前から称号(Mr.とかMrs.とか)を取り出す処理を書いてみます。
from tqdm import tqdm tqdm.pandas() df['Title'] = df.progress_apply(lambda x: x['Name'].split()[1], axis=1) df.head().iloc[:, -5:]
プログレスバーが出るので、行数が多い場合でも固まってるんじゃ?という心配をせずに済みます。
さいごに
pandasの便利機能や、こういう処理がしたい場合の賢い書き方、みたいなものがあればTwitterやコメントでぜひ教えてください!
Kaggle、がんばっていきましょう! (現在行われているHome Creditコンペが面白いです)
前回の記事: