Pandas メジャーアップデート(0.20.1)の要点〜高速 I/O、集約関数強化など
こんにちは。吉田弁二郎です。
先日(5月5日)、pandas の最新版 0.20.1 がリリースされました。agg/transform
メソッドがgroupby
しなくても使えるようになり、10倍以上高速な I/O を実現する feather-format が(試験的に)導入され、スライスの際に頻繁に利用されていた.ix
インデクサが deprecated となるなど、全般的に着実な改善もしくは変更がされている印象です。以下、リリースノートのハイライト部分より、目についたものをピックアップしていきます。
agg/transform
が Series/DataFrame に対して直接使える
従来はgroupby
メソッドを呼んだ際につくられる SeriesGroupBy/DataFrameGroupBy オブジェクトで利用可能だった集約関数agg
およびtransform
が Series/DataFrame オブジェクトから直接呼べるようになりました。例えば、
df = pd.DataFrame({'x': np.random.randn(5), 'y': np.random.randn(5)}) # x y # 0 0.405046 -0.544307 # 1 0.378932 0.845846 # 2 0.463125 2.251753 # 3 -0.586262 1.705797 # 4 0.408864 0.436262 transformed = df.transform(lambda x: (x - x.mean())/x.std()) transformed.describe() # x y # count 5.000000e+00 5.000000e+00 # mean -4.440892e-17 -3.330669e-17 # std 1.000000e+00 1.000000e+00 # 以下省略
という感じで、各列ごとに正規化したりするのに使えて便利ですね。
http://pandas.pydata.org/pandas-docs/stable/whatsnew.html#agg-api-for-dataframe-series
10倍以上の書き込み/4倍以上の読み込み速度を実現する feather-format をサポート
新しいデータフォーマット feather-format が pandas の read/write で処理できるようになりました。実際にどの程度速度差があるのか見てみたいと思います。
テスト用のデータセットとして、映画評価データ IMDB 5000 Movie Dataset | Kaggle を使います。ダウンロードして入手できる csv ファイルのサイズは約 1.4MB ですが、通常業務で向き合うデータサイズから見ると小さすぎるのでかさ増しした状態でやりましょう。
movie = pd.read_csv('movie_metadata.csv') movie_100x = pd.concat([movie for i in range(100)], ignore_index=True) # サイズを100倍にかさ増し
まずは書き込みから。
%timeit movie_100x.to_csv("movie_metadata_100x.csv", index=False) 14.4 s ± 257 ms per loop (mean ± std. dev. of 7 runs, 1 loop each) %timeit movie_100x.to_feather("movie_metadata_100x.feather") 1.38 s ± 138 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
となり約10倍以上の高速化がされていると分かります。次に読み込みは
%timeit pd.read_csv("movie_metadata_100x.csv") 5.66 s ± 207 ms per loop (mean ± std. dev. of 7 runs, 1 loop each) %timeit pd.read_feather("movie_metadata_100x.feather") 1.25 s ± 24.3 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
と約4倍以上のパフォーマンスが出ています。高速化の倍率はおそらくデータサイズに依存して変わると思いますが、いずれにしても、大きなデータを扱う際には有望なファイル形式が pandas で使えるようになったと言えそうです。ただし、Python 版の feather 開発者である Wes McKinney によると(pandas の考案者・開発者でもある)
Note to users: Feather should be treated as alpha software. In particular, the file format is likely to evolve over the coming year. Do not use Feather for long-term data storage.
ということなので、本番利用は今後の開発を待った方がいいかもしれません。
なお、ファイルサイズは、変換後のmovie_metadata.feather
が約 1.9MB と元の 1.4MB からはかなり大きくなっています。
http://pandas.pydata.org/pandas-docs/version/0.20/io.html#feather
.ix
インデクサが deprecated に
これは個人的にかなり衝撃を受けた項目です。DataFrame からのデータ抽出に便利に使える.ix
インデクサが廃止予定となりました。pandas 0.20.1 では警告が出るのみで利用自体は可能だというものの、将来的には不可能になります。代わりに.loc
もしくは.iloc
を使うことで、検索対象が「ラベル」なのか「位置(数値)」なのか表現を厳密にする必要があります。
http://pandas.pydata.org/pandas-docs/version/0.20/whatsnew.html#deprecate-ix
インデックスに対してもgroupby
できる
groupby
関数のby
引数として、インデックスを指定できるようになりました(これまでは KeyError が出ていた)。
df = pd.DataFrame({'x': np.random.randn(5), 'y': np.random.randn(5)}, index=list('aabbc')) df.index.name = 'idx' # x y # idx # a -1.527253 0.735587 # a -0.336519 -0.757381 # b -0.142629 -1.385499 # b -0.220486 -0.306491 # c -1.858252 1.056412 df.groupby('idx').sum() # x y # idx # a -1.863772 -0.021794 # b -0.363115 -1.691990 # c -1.858252 1.056412
pivot_table
あたりを使って階層的インデックスづけされた DataFrame を得た後、インデックスに関して集約関数をかませたい時とかに使えそうです。
http://pandas.pydata.org/pandas-docs/version/0.20/whatsnew.html#groupby-enhancements
エクセル出力時にスタイルを変更できる
こちらは下記リンクを見ていただくのが一番わかり易いかと思います。DataFrame をto_excel
経由でエクセル形式で出力する際、セルや文字の色付け、フォーマッティングなどのスタイリング処理が CSS2.2 ベースでできます。データ分析結果をプランナー等に渡す際、どうしてもエクセルで見やすくする必要があるといった状況で有用な感じです。
http://pandas.pydata.org/pandas-docs/stable/whatsnew.html#excel-output-for-styled-dataframes
動作確認環境
OSX: 10.11.6
Python: 3.6.1
IPython: 6.0.0
Numpy: 0.12.1
Pandas: 0.20.1