maxymoo
maxymoo

Reputation: 36555

Pandas round to the nearest "n"

Numeric series have a nice rounding method for rounding to powers of ten, eg

>>> pd.Series([11,16,21]).round(-1)
0    10
1    20
2    20
dtype: int64

Is there an equivalently nice syntax for rounding to the nearest 5 (or other non-power of 10)? I'm sort of wishing that round could take non-integer values?

Upvotes: 25

Views: 35337

Answers (4)

Sanyam
Sanyam

Reputation: 1

I think some the above suggestions wont work when series contains a number 1 or less. here is an improved answer.

import pandas as pd
import numpy as np

# Example DataFrame
data = {'A': [1.1, 22, 48, 17], 'B': [41, 18, 0.3, 99]}

df = pd.DataFrame(data)

# Round up to the nearest 10th
df_rounded = np.ceil(df / 10.0) * 10

print(df_rounded)

Upvotes: 0

storm125
storm125

Reputation: 570

One of the answers suggests using apply to pass a lambda which divides by 10, rounds it to nearest integer, and then multiplies by 10. Instead, you can take advantage of vectorisation in pandas by doing the following:

>>> s = pd.Series([11, 16, 21])
>>> (s / 10).round().astype(int) * 10
0    10
1    20
2    20
dtype: int64

Upvotes: 16

maxymoo
maxymoo

Reputation: 36555

I guess I could do this:

def round_down_to_nearest(self, n):
    return (self // n) * n

pd.Series.round_down_to_nearest = round_down_to_nearest

Upvotes: 4

Andy
Andy

Reputation: 50640

You can utilize a custom rounding function and apply it to your series.

import pandas as pd

def custom_round(x, base=5):
    return int(base * round(float(x)/base))

df = pd.Series([11,16,21]).apply(lambda x: custom_round(x, base=5))

Now you just need to adjust the base to get to the nearest value you want.

A couple examples:

Base = 5:

0    10
1    15
2    20
dtype: int64

Base = 7

0    14
1    14
2    21
dtype: int64

Base = 3

0    12
1    15
2    21
dtype: int64

Your goal of non-integer values can be done too.

def custom_round(x, base=5):
    return base * round(float(x)/base)

df = pd.Series([11.35,16.91,21.12]).apply(lambda x: custom_round(x, base=.05))

By rounding to the nearest 0.05, you'll get these results (notice I modified your series slightly for this example):

0    11.35
1    16.90
2    21.10
dtype: float64

If you keep your original series of integers, this apply will change your series into float values:

Upvotes: 38

Related Questions