はじめに
フィギュアスケートの採点では、複数の審査員がつけた得点のうち最大と最小を除いた平均が用いられます。
同様の統計量を求める場面は多いと思うのですが、Pandasの実装が見つけられなかったので実装してみました。
Rでの実装はこちらが参考になると思います。
実装
基本形
Seriesをソートして先頭と末尾を除いた要素の平均を求めます。基本的にこの形にして実装します。
>>> s = pd.Series([2, 0, 1, 8, 0, 6, 2, 6])
>>> s.sort_values()[1:-1].mean()
2.8333333333333335
DataFrameへの適用
単一列を集計する場合
次の図のようなデータが与えられたときに、A列でグルーピングしてB列を集計します。ちょうどA列が選手の名前で、B列が審査員の得点のイメージです。
GroupBy.apply
を使って次のように書きます。
>>> df.groupby('A')['B'].apply(lambda x: x.sort_values()[1:-1].mean())
A B
a 1
b 2.3333333333333335
複数列を集計する場合
GroupBy.apply
の中でDataFrame.apply
を使います。
>>> df.groupby('A')[['B', 'C']].apply(lambda x: x.apply(lambda y: y.sort_values()[1:-1].mean()))
A B C
a 1 3
b 2.3333333333333335 4.666666666666667
行を集計する場合
DataFrame.apply
をaxis=1
で使います。
>>> df[['B', 'C', 'D', 'E', 'F']].apply(lambda x: x.sort_values()[1:-1].mean(), axis=1)
1 1
2 2.3333333333333335