Reputation: 31
My input looks like below:
Name Sep Oct
Amy 833.33 833.33
Eve 20774.5 0
My Expected Output is:
Name Sep Oct
Amy 833 833
Eve 20775 0
When I apply np.ceil to round 0.5 to nearest integer, my output becomes:
Name Sep Oct
Amy 834 834
Eve 20775 0
How to apply np.ceil
only to values having decimal greater than or equal to 0.5? Or is there any other way to get my desired output.
Upvotes: 3
Views: 2761
Reputation: 11
inpt_strg = '''
Name Sep Oct
Amy 833.33 833.33
Eve 20774.5 0
'''
s_lst = inpt_strg.splitlines()
n_lst = [list(str.split(" ")) for str in s_lst]
def fl(i):
try: return float (i)
except ValueError: return i
def rd(i):
if isinstance(i, float):
if (abs(i)%1)*10>=5:return int (i) + 1
else: return int (i)
else: return i
r_lst = [[rd(fl(i)) for i in sub] for sub in n_lst]
from tabulate import tabulate
print(tabulate(r_lst,tablefmt='plain'))
Output:-
Name Sep Oct
Amy 833 833
Eve 20775 0
Upvotes: 0
Reputation: 31
I fixed my output by applying the following query:
df['Sep'][(df['Sep']%1) >= 0.5] = df['Sep'].apply(np.ceil)
Upvotes: 0
Reputation: 41327
np.ceil()
always rounds up while np.floor()
always rounds down.
np.round()
is close but does not always round up for *.5. As @Mark Ransom suggested, it turns out this rounding inconsistency is by design (emphasis added):
numpy.around(a, decimals=0, out=None)
Evenly round to the given number of decimals.
So for example 20774.5 rounds down to 20774 while 20775.5 rounds up to 20776.
There are some workarounds in this SO post. Here's one way to applymap()
one of those workarounds:
df[['Sep', 'Oct']] = df[['Sep', 'Oct']].applymap(
lambda x: np.ceil(x) if float(x) % 1 >= 0.5 else np.round(x))
# Name Sep Oct
# 0 Amy 833.0 833.0
# 1 Eve 20775.0 0.0
Upvotes: 1
Reputation: 816
You could use the np.round
and cast to int
.
like this:
int(np.round(833.33))
Output:
833
Upvotes: 2