こんにちは。sinyです。
この記事では、ちょっとマニアックなpythonのテクニック(Noneを返すメソッドの標準出力結果を再利用する方法)についてご紹介します。
例えば、何かしらの情報を標準出力してくれるけどNoneをReturnするような標準メソッドがあった場合、出力結果を変数に格納してもNoneが返ってきてしまうので、出力結果をプログラムの中で再利用するといったことができません。
これだけだとちょっとイメージしづらいかと思いますので、具体例で説明します。
pandasでデータフレームの統計サマリーを表示してくれるDataFrame.infoメソッドは皆さんもよくご存じだと思います。
infoメソッドは戻り値がNoneなので、出力結果を変数に代入してもNoneが格納されるだけなので出力結果を再利用することができません。
例えば以下のようにDataFrameを定義します。
import pandas as pd import numpy as np df = pd.DataFrame({ 'column_1': np.random.choice(['a', 'b', 'c'], 10 ** 2), 'column_2': np.random.choice(['a', 'b', 'c'], 10 ** 2), 'column_3': np.random.choice(['a', 'b', 'c'], 10 ** 2) })
df.head()を実行すると以下のようにcolumn_1~3はランダムにa,b,cから選択されたデータになってます。
df.info()を実行すると以下のようにサマリーが表示されますよね。
df.info() #実行結果 <class 'pandas.core.frame.DataFrame'> RangeIndex: 100 entries, 0 to 99 Data columns (total 3 columns): column_1 100 non-null object column_2 100 non-null object column_3 100 non-null object dtypes: object(3) memory usage: 2.4+ KB
ここで、df.info()の結果を変数に入れて表示すると・・・
上記のように「None」が返ってきます。
これは、pandasのinfoメソッドの戻り値がNone(仕様)であるためです。
こんなケースでは、io.StringIOを使うことでdf.info()の出力結果を変数に格納することができます。
DataFrame.infoの出力はデフォルトでsys.stdoutなのですが、bufferにパイプ処理することで変数に格納したりファイルに内容を書き込んだりすることができます。
具体的には以下のようなコードで実現できます。
import io buffer = io.StringIO() df.info(buf=buffer) df_info = buffer.getvalue().split("\n") for i in df_info: print(i) #実行結果 <class 'pandas.core.frame.DataFrame'> RangeIndex: 100 entries, 0 to 99 Data columns (total 3 columns): column_1 100 non-null object column_2 100 non-null object column_3 100 non-null object dtypes: object(3) memory usage: 2.4+ KB
ファイルに書き込みたければ以下のようにすればOKです。
with open("df_info.txt", "w",encoding="utf-8") as f: f.write(df_info)
Djangoで機械学習のフレームワークを自作しているのですが、分析対象のデータサマリーをWEB画面に表示したいようなケースでは今回のテクニックを使うことで実現できます。
以上、「【python】pandasのちょっとマニアックな使い方」でした。