#はじめに
今までの関連記事です。
dplyr使いのためのpandas 基礎編
dplyr使いのためのpandas スライスsliceとインデックスindex編
#マルチカラム?
pandasのdataframeはRのdataframeとの大きな違いにMultiIndexという構造があります。
階層型(hierarchical)とも、多重とも訳されているようです。どのようなものか、例を出した方が分かりやすいので、早速例を見ていきましょう。
##実例と使用データ
基礎編同様、相模原市オープンデータライブラリで公開されている駅別乗降人員の推移を使用しています。
路線名=trainline、駅名=station、年度=year_YYYYに適宜列名を変更して使用しています。
#MultiIndex
こう実行すると、
import pandas as pd
import numpy as np
#trainlineとstationごとに集計(見やすさのため一部抜粋)
dataframe.\
query('trainline=="相模線"').\
groupby(['trainline','station']).\
agg({"year_1975":"mean","year_1980":[sum,max,np.mean] })
こんな感じの出力結果になります。
trainline |
station |
year_1975 mean |
year_1980 sum |
max |
mean |
---|---|---|---|---|---|
相模線 | 上溝駅 | 4526 | 4562 | 4562 | 4562 |
下溝駅 | 836 | 856 | 856 | 856 | |
南橋本駅 | 2536 | 2006 | 2006 | 2006 | |
原当麻駅 | 1874 | 2930 | 2930 | 2930 | |
番田駅 | 1218 | 2334 | 2334 | 2334 | |
相武台下駅 | 700 | 794 | 794 | 794 |
groupbyで指定したtrainlineとstationごとに集計されています。この太字の部分がMulitiIndexです。行のindexがgroupbyで指定したtrainline-station、列のindexがyear_1975-mean, year_1980-sum/max/meanと階層化されています。R:dataframeとの大きな違いはこの列の階層構造(マルチカラム)があることです。
R:dplyrにおけるdataframeは列名が操作の基本となり、列名は常に絶対的なものです。
##マルチカラムの操作
例として乗降人数が1980年のmaxが2500人未満かつ1975年の平均が1000人より多い駅を抽出します。
dataframe %>%
filter(trainline =="相模線") %>%
group_by(trainline, station) %>%
summarise(year_1975_mean = mean(year_1975, na.rm=T),
year_1980_sum = sum(year_1980, na.rm=T),
year_1980_max = max(year_1980),
year_1980_mean = mean(year_1980, na.rm=T)) %>%
filter(year_1975_mean > 1000 & year_1980_max < 2500)
#マルチカラム操作時に必要なおまじない(スライスを可能にする)
idx = pd.IndexSlice
#集計後マルチカラムを指定して行選択
dataframe.\
query('trainline=="相模線"').\
groupby(['trainline','station']).\
agg({"year_1975":"mean","year_1980":[sum,max,np.mean] }).tail(6).\
loc[lambda df: idx[ df[('year_1975','mean')] > 1000 ] & idx[df[('year_1980','max')] < 2500] ]
集計後の行選択はloc[]とidx[]を使用します。どうやらquery()はマルチカラムを指定できないようです。
#補足
##loc? スライス?
dplyr使いのためのpandas スライスsliceとインデックスindex編にまとめました。
##lambda
スライスなどで明示的にdataframeを指定しなければならない場合、lambda式を使うと便利です。lambdaは無名関数というもので、defの親戚のようなものです。使い方は式の先頭に以下のように記述すれば以降はdataframe名称を指定した引数(ここではdf)で代用できます。
#lambda 引数:条件式
lambda df:
#例:assignでカラムを追加する場合
dataframe.assign(lambda df: new_column = df.year_1975 * 2)
#まとめ
MultiIndexの操作はR:dataframeにはない機能です。
少々ややこしいですが、dplyr同様の操作ができるよう方法を調べてみました。