Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Pandas round to the nearest "n"

Tags:

python

pandas

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?

like image 737
maxymoo Avatar asked Nov 02 '16 03:11

maxymoo


People also ask

How do pandas only show 2 decimal places?

Use pandas.display. float_format to "{:,. 2f}". format to display float values to two decimal places.

How do you round down to the nearest 5 in Python?

Round a Number Down to the nearest 5 in Python #Call the math. floor() method passing it the number divided by 5 . Multiply the result by 5 . The result of the calculation is the number rounded down to the nearest 5 .


2 Answers

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:

like image 99
Andy Avatar answered Sep 26 '22 01:09

Andy


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
like image 23
storm125 Avatar answered Sep 22 '22 01:09

storm125