LoginSignup
3
4

More than 5 years have passed since last update.

dplyr使いのためのpandas マルチカラム操作編

Last updated at Posted at 2018-11-29

はじめに

今までの関連記事です。
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人より多い駅を抽出します。

R_dplyr:集計-マルチカラム操作
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)
Python_pandas:集計-マルチカラム操作
#マルチカラム操作時に必要なおまじない(スライスを可能にする)
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 引数:条件式
lambda df:
#例:assignでカラムを追加する場合
dataframe.assign(lambda df: new_column = df.year_1975 * 2)

まとめ

MultiIndexの操作はR:dataframeにはない機能です。
少々ややこしいですが、dplyr同様の操作ができるよう方法を調べてみました。

3
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
4