Rookie
Rookie

Reputation: 305

Use Pandas to round based on another column

I have a dataframe where 1 column is a list of values and another is the number of digits I need to round to. It looks like this:

  ValueToPlot  B_length
0       13.80       1.0
1       284.0       0.0
2         5.9       0.0
3        1.38       1.0
4       287.0       0.0

I am looking for an output that looks like this:

  ValueToPlot  B_length  Rounded
0       13.80       1.0     13.8
1       284.0       0.0      284
2         5.9       0.0        6
3        1.38       1.0      1.4
4       287.0       0.0      287

Lastly, I would like the Rounded column to be in a string format, so the final result would be:

  ValueToPlot  B_length  Rounded
0       13.80       1.0   '13.8'
1       284.0       0.0    '284'
2         5.9       0.0      '6'
3        1.38       1.0    '1.4'
4       287.0       0.0    '287'

I have attempted to use apply function in Pandas but have not been successful. I would prefer to avoid looping if possible.

Upvotes: 1

Views: 679

Answers (2)

BENY
BENY

Reputation: 323226

A little long ... but work

df.apply(lambda x : str(round(x['ValueToPlot'],int(x['B_length']))) if x['B_length']>0 else str(int(round(x['ValueToPlot'],int(x['B_length'])))),axis=1)
Out[1045]: 
0    13.8
1     284
2       6
3     1.4
4     287
dtype: object

Upvotes: 1

piRSquared
piRSquared

Reputation: 294218

Use chained formats
'{{:0.{}f}}'.format(3) evaluates to '{:0.3f}'. The double '{{}}' tells format to escape the '{}'. Then '{:0.3f}'.format(1) evaluates to 1.000. We can capture this concept by chaining.

f = lambda x: '{{:0.{}f}}'.format(int(x[1])).format(x[0])

df.assign(Rounded=df.apply(f, 1))

   ValueToPlot  B_length Rounded
0        13.80       1.0    13.8
1       284.00       0.0     284
2         5.90       0.0       6
3         1.38       1.0     1.4
4       287.00       0.0     287

A little more explicit with the column names

f = lambda x: '{{:0.{}f}}'.format(int(x['B_length'])).format(x['ValueToPlot'])

df.assign(Rounded=df.apply(f, 1))

   ValueToPlot  B_length Rounded
0        13.80       1.0    13.8
1       284.00       0.0     284
2         5.90       0.0       6
3         1.38       1.0     1.4
4       287.00       0.0     287

I generally like to use assign as it produces a copy of the data frame with a new column attached. I can edit the original data frame

f = lambda x: '{{:0.{}f}}'.format(int(x[1])).format(x[0])

df['Rounded'] = df.apply(f, 1)

Or I can use assign with an actual dictionary

f = lambda x: '{{:0.{}f}}'.format(int(x[1])).format(x[0])

df.assign(**{'Rounded': df.apply(f, 1)})

Upvotes: 2

Related Questions