注意
本記事の方法では、表現誤差のある数値(0.30000000000000004
といったもの)が含まれている場合、その数値に引きずられて桁数が大きくなってしまいます。
使用する際は、表現誤差のある数値があるかを確認すると良いでしょう。(もしくは、得られた桁数が異常に大きくない事を確認すると良いでしょう。)
経緯
pandas.Series の interpolate メソッドで補間した際に、小数点以下の桁数が増えてしまいました。
例:
python
import pandas as pd
# 小数点以下 1桁 のデータ
series = pd.Series([0.2, np.nan, 0.5])
# 補間すると 2桁 になってしまう
series.interpolate() # => [0.20, 0.35, 0.50]
そこで、補間前に小数点以下桁数を記録しておき、補間後にその桁数に丸める事にしました。
この過程で、「数値の入った pd.Series を入力すると、最大で小数点以下何桁まであるか調べるメソッド」を作成したので、この記事で共有したいと思います。
作成したメソッド
python
# 最大で小数点以下何桁まであるか調べる
def calc_n_digit_after_the_decimal_point(series):
# 文字列に変換
str_series = series.map(lambda x: str(x))
# 少数以下があるものを抜き出す
# 「 x[-2:] != '.0' 」では、「1.0」の様に float型だけど値は整数である様なものかを判定している
mask = str_series.map(lambda x: ('.' in x) & (x[-2:] != '.0'))
only_decimal_str_series = str_series[mask]
# 少数がある場合
if only_decimal_str_series.size > 0:
# 少数以下の桁数の最大値を取得
# この桁に四捨五入する
n_digit = only_decimal_str_series.map(lambda x: len(x.split('.')[1])).value_counts().sort_index().index.max()
# 少数がない場合
else:
n_digit = 0
return n_digit
使用例
python
# 小数点以下 1桁 のデータ
series = pd.Series([0.2, np.nan, 0.5])
# 桁数を記録
n_digit = calc_n_digit_after_the_decimal_point(series)
# 補間
series = series.interpolate()
# 記録しておいた桁数に丸める
series.round(n_digit) # => [0.2, 0.4, 0.5]