IPythonノートブックに論文を書こうとしていますが、表示形式にいくつかの問題が発生しました。次のデータフレームdf
があるとします。var1
およびvar2
を2桁の10進数に、var3
をパーセンテージにフォーマットする方法はありますか。
var1 var2 var3
id
0 1.458315 1.500092 -0.005709
1 1.576704 1.608445 -0.005122
2 1.629253 1.652577 -0.004754
3 1.669331 1.685456 -0.003525
4 1.705139 1.712096 -0.003134
5 1.740447 1.741961 -0.001223
6 1.775980 1.770801 -0.001723
7 1.812037 1.799327 -0.002013
8 1.853130 1.822982 -0.001396
9 1.943985 1.868401 0.005732
内部の数値は100倍されません。 -0.0057 = -0.57%。
round関数を使用して値を置き換え、パーセント値の文字列表現をフォーマットします。
df['var2'] = pd.Series([round(val, 2) for val in df['var2']], index = df.index)
df['var3'] = pd.Series(["{0:.2f}%".format(val * 100) for val in df['var3']], index = df.index)
Round関数は、関数の2番目の引数として提供された小数点以下の桁数に浮動小数点数を丸めます。
文字列の書式設定により、必要に応じて数値を表すことができます。 f
の前の数字を変更することにより、表示される小数点以下の桁数を変更できます。
追伸あなたの「パーセンテージ」の数値がすでに100倍されているかどうかはわかりませんでした。
受け入れられた答えは、プレゼンテーション目的で生データを変更することを示唆しています。これは一般的には望まないことです。これらの列でさらに分析を行う必要があり、丸めで失われた精度が必要だと想像してください。
あなたの場合、データフレームの個々の列のフォーマットを変更できます:
output = df.to_string(formatters={
'var1': '{:,.2f}'.format,
'var2': '{:,.2f}'.format,
'var3': '{:,.2%}'.format
})
print(output)
'{:,.2%}'.format(0.214)
は21.40%
を生成するため、100を掛ける必要はありません。
ニースHTMLテーブルはもうありませんが、テキスト表現があります。 HTMLを使い続ける必要がある場合は、代わりにto_html
関数を使用してください。
from IPython.core.display import display, HTML
output = df.to_html(formatters={
'var1': '{:,.2f}'.format,
'var2': '{:,.2f}'.format,
'var3': '{:,.2%}'.format
})
display(HTML(output))
更新
pandas 0.17.1の時点で、作業が楽になり、すぐに美しいhtmlテーブルを取得できます。
df.style.format({
'var1': '{:,.2f}'.format,
'var2': '{:,.2f}'.format,
'var3': '{:,.2%}'.format,
})
Floatのデフォルト形式を設定することもできます:
pd.options.display.float_format = '{:.2f}%'.format
@linquが示唆するように、プレゼンテーション用にデータを変更しないでください。 pandas 0.17.1以降、(条件付き)フォーマットが簡単になりました。 ドキュメント の引用:
DataFrame.style
プロパティを使用して、内部のデータに応じてDataFrame
の視覚スタイリングである条件付き書式設定を適用できます。これはpandas.Styler
オブジェクトを返すプロパティで、DataFrames
のフォーマットと表示に便利なメソッドがあります。
たとえば、次のようになります(通常のテーブルはJupyterに表示されます)。
df.style.format({
'var1': '{:,.2f}'.format,
'var2': '{:,.2f}'.format,
'var3': '{:,.2%}'.format,
})
より広い範囲の列で行う必要がある場合は、別の方法で行う必要があります
applymapを使用
df[['var1','var2']] = df[['var1','var2']].applymap("{0:.2f}".format)
df['var3'] = df['var3'].applymap(lambda x: "{0:.2f}%".format(x*100))
applymapは、複数の列に関数を適用する必要がある場合に役立ちます。この特定の例では、基本的に以下の略語です。
df[['var1','var2']].apply(lambda x: map(lambda x:'{:.2f}%'.format(x),x),axis=1)
applymapの以下のすばらしい説明、applymap:
ただやる:
df.style.format({'var1': "{:.2f}",'var2': "{:.2f}",'var3': "{:.2%}"})
与える:
var1 var2 var3
id
0 1.46 1.50 -0.57%
1 1.58 1.61 -0.51%
2 1.63 1.65 -0.48%
3 1.67 1.69 -0.35%
4 1.71 1.71 -0.31%
5 1.74 1.74 -0.12%
6 1.78 1.77 -0.17%
7 1.81 1.80 -0.20%
8 1.85 1.82 -0.14%
9 1.94 1.87 0.57%
少し読みやすく、エレガントで、一般的(YMMV)と考えられる受け入れられた答えへの同様のアプローチとして、map
メソッドを活用できます。
# OP example
df['var3'].map(lambda n: '{:,.2%}'.format(n))
# also works on a series
series_example.map(lambda n: '{:,.2%}'.format(n))
パフォーマンスの面では、これはOPソリューションよりもかなり近い(わずかに遅い)です。
余談ですが、pd.options.display.float_format
ルートに進むことを選択した場合は、コンテキストマネージャーを使用してこの パラレルnumpyの例 に従って状態を処理することを検討してください。