【Pandas数値処理】四捨五入・偶数丸め・切り捨て・切り上げを自在に操る方法

Pandasでデータ分析をしていると、「小数点以下を四捨五入したい」「小数点以下を切り捨てたい」「整数に切り上げたい」といった数値処理が必要になることがあります。

特に、Pandasのround()は一般的な「四捨五入」と少し異なり、偶数丸め(銀行丸め)を採用している点には注意が必要です。

この記事では、Pandasを使った数値処理について、以下を具体的なコードとともに解説します。

  • 四捨五入
  • 偶数丸め
  • 小数点以下の切り捨て
  • 小数点以下の切り上げ
  • 指定した桁数での丸め
  • DataFrame全体の丸め
  • numpy.floor()numpy.ceil()との違い
  • 「5」をどう処理するか
  • 金額や集計データでの注意点

Pandasの数値処理を理解する

Pandasでは、SeriesやDataFrameに対して簡単に数値処理を行えます。 代表的な方法は次のとおりです。

処理 主な方法
丸め round()
偶数丸め round()
切り捨て numpy.floor()
切り上げ numpy.ceil()
0方向への切り捨て numpy.trunc()
小数点以下の桁数指定 round(n)

例えば、次のDataFrameを用意します。

import pandas as pd

df = pd.DataFrame({
    "price": [1.4, 1.5, 1.6, 2.4, 2.5, 2.6]
})

print(df)

実行すると、次のようになります。

   price
0    1.4
1    1.5
2    1.6
3    2.4
4    2.5
5    2.6

Pandasで四捨五入する方法

Pandasで数値を丸める場合は、round()メソッドを使うのが基本です。

df["price"].round()

例えば、次のように使用します。

import pandas as pd

df = pd.DataFrame({
    "price": [1.4, 1.5, 1.6, 2.4, 2.5, 2.6]
})

df["rounded"] = df["price"].round()

print(df)

結果は次のようになります。

   price  rounded
0    1.4      1.0
1    1.5      2.0
2    1.6      2.0
3    2.4      2.0
4    2.5      2.0
5    2.6      3.0

ここで、1.5 → 22.5 → 2となっていることに注目してください。

「2.5を3にしたい」と思った方もいるかもしれません。 これはPandasのround()が、単純な四捨五入ではなく、 偶数丸め(round half to even)を採用しているためです。

Pandasのround()は「偶数丸め」

Pandasのround()では、丸める対象がちょうど「5」の場合、近い偶数に丸めます。

例えば、次のようになります。

1.5 → 2
2.5 → 2
3.5 → 4
4.5 → 4
5.5 → 6

つまり、1.5 → 2は2が偶数なので2へ、 2.5 → 2も2が偶数なので2へ、 3.5 → 4は4が偶数なので4へ丸められます。

なぜ偶数丸めを使うのか?

偶数丸めは、同じ方向に丸め続けることによる誤差の偏りを抑える目的で利用されます。

大量のデータを丸める場合、単純に「5以上なら切り上げる」というルールでは、 丸め処理によって値が一方向に偏る可能性があります。

そのため、統計処理や科学技術計算などでは偶数丸めが利用されることがあります。

小数点以下の桁数を指定する

round()には、丸める桁数を指定できます。

df["price"].round(1)

これで、小数点以下1桁に丸めることができます。

import pandas as pd

s = pd.Series([1.234, 2.345, 3.456])

print(s.round(2))

結果は次のようになります。

0    1.23
1    2.34
2    3.46
dtype: float64

小数点以下2桁にする

小数点以下2桁に丸める場合は、次のように記述します。

df["price"].round(2)

例えば、次のような変換になります。

1.2345 → 1.23
2.3456 → 2.35
3.9999 → 4.00

DataFrame全体を丸める

DataFrame全体に対してround()を使うこともできます。

df.round(2)

例えば、次のコードを実行します。

import pandas as pd

df = pd.DataFrame({
    "price": [123.456, 234.567],
    "rate": [1.2345, 2.3456]
})

print(df.round(2))

結果は次のようになります。

     price  rate
0   123.46  1.23
1   234.57  2.35

列ごとに丸める桁数を変える

DataFrameのround()では、辞書を利用して列ごとに桁数を指定できます。

df.round({
    "price": 0,
    "rate": 2
})

例えば、次のように使用します。

import pandas as pd

df = pd.DataFrame({
    "price": [123.456, 234.567],
    "rate": [1.2345, 2.3456]
})

result = df.round({
    "price": 0,
    "rate": 2
})

print(result)

結果:

   price  rate
0  123.0  1.23
1  235.0  2.35

この方法は、複数の数値列を扱う実務のデータ処理で非常に便利です。

Pandasで小数点以下を切り捨てる

四捨五入ではなく、必ず下方向に丸めたい場合は、 numpy.floor()を利用できます。

import numpy as np

df["floor"] = np.floor(df["price"])

例えば、次のコードを実行します。

import pandas as pd
import numpy as np

s = pd.Series([1.1, 1.9, 2.1, 2.9])

print(np.floor(s))

結果:

0    1.0
1    1.0
2    2.0
3    2.0
dtype: float64

つまり、次のようになります。

1.1 → 1
1.9 → 1
2.1 → 2
2.9 → 2

Pandasで小数点以下を切り上げる

小数点以下を切り上げる場合は、numpy.ceil()を使います。

import numpy as np

df["ceil"] = np.ceil(df["price"])

例えば、次のコードです。

import pandas as pd
import numpy as np

s = pd.Series([1.1, 1.9, 2.1, 2.9])

print(np.ceil(s))

結果:

0    2.0
1    2.0
2    3.0
3    3.0
dtype: float64

つまり、次のようになります。

1.1 → 2
1.9 → 2
2.1 → 3
2.9 → 3

floorとceilの違い

floor()ceil()は次のように覚えると分かりやすいでしょう。

元の値 floor() ceil()
1.1 1 2
1.5 1 2
1.9 1 2
2.1 2 3
2.9 2 3

floor = 下方向
ceil = 上方向

マイナス値では注意が必要

floor()は「小数点以下を切り捨てる」と説明されることが多いですが、 正確には負の無限大方向へ丸める処理です。

import numpy as np

s = pd.Series([-1.1, -1.5, -1.9])

print(np.floor(s))
print(np.ceil(s))

結果は次のようになります。

floor
-2
-2
-2

ceil
-1
-1
-1

例えば、

-1.1 → floor → -2
-1.1 → ceil  → -1

となります。

0方向に切り捨てるならnumpy.trunc()

「小数部分を取り除いて整数部分だけにしたい」という場合には、 numpy.trunc()が便利です。

import numpy as np

s = pd.Series([-1.9, -1.1, 1.1, 1.9])

print(np.trunc(s))

結果:

0   -1.0
1   -1.0
2    1.0
3    1.0
dtype: float64

trunc()0に近づく方向へ丸めます。

元の値 floor() trunc() ceil()
-1.9 -2 -1 -1
-1.1 -2 -1 -1
1.1 1 1 2
1.9 1 1 2

負の値を扱う場合は、この違いを理解しておくことが重要です。

10の位・100の位で四捨五入する

round()は小数点以下だけでなく、整数部分の桁も指定できます。

例えば、次のコードです。

s.round(-1)

-1を指定すると、10の位で丸めます。

import pandas as pd

s = pd.Series([123, 156, 178, 245])

print(s.round(-1))

結果:

0    120
1    160
2    180
3    240
dtype: int64

また、

s.round(-2)

とすると、100の位で丸めることができます。

123 → 100
156 → 200
178 → 200
245 → 200

1000円単位に丸める

売上データなどを扱う場合、1000円単位に丸めたいケースがあります。

df["sales"].round(-3)

例えば、次のコードを実行します。

import pandas as pd

df = pd.DataFrame({
    "sales": [12345, 15678, 18432, 25321]
})

df["rounded"] = df["sales"].round(-3)

print(df)

結果:

   sales  rounded
0  12345  12000
1  15678  16000
2  18432  18000
3  25321  25000

このように、データを見やすく加工するときにもround()は便利です。

1000円単位で切り捨てる

1000円単位で切り捨てたい場合は、floor()を利用できます。

1000で割ってからfloor()し、最後に1000を掛ける方法が分かりやすいでしょう。

df["sales_floor"] = np.floor(df["sales"] / 1000) * 1000

例えば、次のようになります。

12345 → 12000
15678 → 15000
18432 → 18000

1000円単位で切り上げる

反対に1000円単位で切り上げる場合は、次のようにします。

df["sales_ceil"] = np.ceil(df["sales"] / 1000) * 1000

例えば、

12345 → 13000
15678 → 16000
18432 → 19000

となります。

「5以上なら切り上げ」の四捨五入をしたい場合

ここはPandas初心者が特に混乱しやすいポイントです。

Pandasのround()は偶数丸めです。

round()

そのため、

2.5 → 2
3.5 → 4

となります。

「小数部分が5以上なら必ず切り上げる」という一般的な四捨五入をしたい場合は、 別の方法を検討する必要があります。

例えば、PythonのDecimalを利用できます。

from decimal import Decimal, ROUND_HALF_UP

def round_half_up(x):
    return float(
        Decimal(str(x)).quantize(
            Decimal("1"),
            rounding=ROUND_HALF_UP
        )
    )

Seriesに適用する場合は、次のようにします。

df["rounded"] = df["price"].apply(round_half_up)

これにより、

1.5 → 2
2.5 → 3
3.5 → 4
4.5 → 5

という「5を切り上げる」方式にできます。

Pandasのround()とDecimalの違い

round() ROUND_HALF_UP
1.4 1 1
1.5 2 2
1.6 2 2
2.4 2 2
2.5 2 3
2.6 3 3
3.5 4 4
4.5 4 5

「5なら必ず切り上げたい」という要件なら、 round()をそのまま使わないようにしましょう。

浮動小数点数には注意

PythonやPandasで小数を扱う場合、浮動小数点数特有の誤差にも注意が必要です。

例えば、

0.1 + 0.2

は数学的には0.3ですが、コンピュータ内部では完全に0.3にならない場合があります。

print(0.1 + 0.2)

すると、次のように表示されることがあります。

0.30000000000000004

そのため、金額などの厳密な丸め処理では、浮動小数点数を単純にround()するだけでよいのか確認することが重要です。

Pandasでよく使う数値処理まとめ

実務では、次のように使い分けると分かりやすいでしょう。

# 偶数丸め
df["value"].round()

# 小数点以下2桁
df["value"].round(2)

# 10の位で丸める
df["value"].round(-1)

# 下方向へ丸める
np.floor(df["value"])

# 上方向へ丸める
np.ceil(df["value"])

# 0方向へ切り捨てる
np.trunc(df["value"])

DataFrameで複数の数値列を処理する

実際のデータ分析では、複数の列をまとめて処理することも多いでしょう。

import pandas as pd
import numpy as np

df = pd.DataFrame({
    "price": [123.45, 234.56, 345.67],
    "rate": [1.234, 2.345, 3.456]
})

df["price"] = df["price"].round(0)
df["rate"] = df["rate"].round(2)

このように列ごとに処理できます。

また、DataFrame全体をまとめて処理するなら、

df = df.round(2)

とするだけです。

Pandasのround()を使うときの注意点

1. 「5は必ず切り上げ」ではない

最も重要なのがこのポイントです。

round()

は偶数丸めなので、

2.5 → 2
4.5 → 4

となる場合があります。

2. floor()は「0方向への切り捨て」ではない

np.floor(-1.5)

は、

-2

になります。

「整数部分だけ残したい」という意味なら、np.trunc()を検討しましょう。

3. 金額では丸めルールを明確にする

請求金額、税額、手数料などでは、

  • 四捨五入
  • 切り捨て
  • 切り上げ
  • 偶数丸め

のどれを採用するかによって結果が変わります。

そのため、業務要件を確認してから実装することが重要です。

よくある質問

Pandasで四捨五入するには?

round()を使います。

df["value"].round()

小数点以下2桁なら、

df["value"].round(2)

です。

Pandasのround()は普通の四捨五入ですか?

厳密には異なります。

Pandasのround()偶数丸め(round half to even)を採用しています。

そのため、

2.5 → 2
3.5 → 4

となります。

Pandasで切り捨てるには?

numpy.floor()が代表的です。

import numpy as np

np.floor(df["value"])

ただし、負の数では「0方向への切り捨て」とは異なるので注意してください。

Pandasで切り上げるには?

numpy.ceil()を利用します。

import numpy as np

np.ceil(df["value"])

小数点以下を削除するだけなら?

numpy.trunc()が便利です。

np.trunc(df["value"])

特に負の数を扱う場合、floor()との違いを理解しておきましょう。

まとめ

Pandasで数値処理を行う場合、目的に応じてメソッドを使い分けることが重要です。

特に覚えておきたいのが次の4つです。

# 偶数丸め
df["value"].round()

# 切り捨て
np.floor(df["value"])

# 切り上げ
np.ceil(df["value"])

# 0方向への切り捨て
np.trunc(df["value"])

また、Pandasのround()は一般的な「5以上なら切り上げる四捨五入」ではなく、 偶数丸めであることが重要なポイントです。

「2.5を3にしたい」のように、5を必ず切り上げる必要がある場合は、 DecimalROUND_HALF_UPなど、要件に合った丸め方式を選択しましょう。

Pandasの数値処理は、データ分析だけでなく、売上集計、料金計算、統計処理、 機械学習の前処理など、さまざまな場面で利用されます。 「どの方向に、どの桁まで丸めるのか」を明確にして使い分けることが、 正確なデータ処理につながります。

プログラミング学習に興味がある方は、まずは無料体験会へ

無料体験会・お申し込みはこちら