ENH: Added DataFrame.round and associated tests by roblevy · Pull Request #10568 · pandas-dev/pandas (original) (raw)

I've found myself doing a lot of DataFrame.to_latex because I'm using pandas to write an academic paper.

I'm constantly messing about with the number of decimal places displayed by doing np.round(df, 2) so thought this flexible round, with different numbers of decimals per column, should be part of the DataFrame API (I'm surprised there isn't already such a piece of functionality.)

Here is an example:

In [9]: df = pd.DataFrame(np.random.random([10, 3]), columns=['a', 'b', 'c'])

In [10]: df
Out[10]: 
          a         b         c
0  0.761651  0.430963  0.440312
1  0.094071  0.242381  0.149731
2  0.620050  0.462600  0.194143
3  0.614627  0.692106  0.176523
4  0.215396  0.888180  0.380283
5  0.492990  0.200268  0.067020
6  0.804531  0.816366  0.065751
7  0.751224  0.037474  0.884083
8  0.994758  0.450143  0.808945
9  0.373180  0.537589  0.809112

In [11]: df.round(dict(b=2, c=4))
Out[11]: 
          a     b       c
0  0.761651  0.43  0.4403
1  0.094071  0.24  0.1497
2  0.620050  0.46  0.1941
3  0.614627  0.69  0.1765
4  0.215396  0.89  0.3803
5  0.492990  0.20  0.0670
6  0.804531  0.82  0.0658
7  0.751224  0.04  0.8841
8  0.994758  0.45  0.8089
9  0.373180  0.54  0.8091

You can also round by column number:

In [12]: df.round([1, 2, 3])
Out[12]: 
     a     b      c
0  0.8  0.43  0.440
1  0.1  0.24  0.150
2  0.6  0.46  0.194
3  0.6  0.69  0.177
4  0.2  0.89  0.380
5  0.5  0.20  0.067
6  0.8  0.82  0.066
7  0.8  0.04  0.884
8  1.0  0.45  0.809
9  0.4  0.54  0.809

and any columns which are not explicitly rounded are unaffected:

In [13]: df.round([1])
Out[13]: 
     a         b         c
0  0.8  0.430963  0.440312
1  0.1  0.242381  0.149731
2  0.6  0.462600  0.194143
3  0.6  0.692106  0.176523
4  0.2  0.888180  0.380283
5  0.5  0.200268  0.067020
6  0.8  0.816366  0.065751
7  0.8  0.037474  0.884083
8  1.0  0.450143  0.808945
9  0.4  0.537589  0.809112

Non-integer values raise a TypeError, as might be expected:

In [15]: df.round({'a':1.2})
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-15-6f51d3fd917d> in <module>()
----> 1 df.round({'a':1.2})

/home/rob/Dropbox/PhD/pandas/pandas/core/frame.py in round(self, places)
   1467 
   1468         if isinstance(places, dict):
-> 1469             new_cols = [col for col in _dict_round(self, places)]
   1470         else:
   1471             new_cols = [col for col in _list_round(self, places)]

/home/rob/Dropbox/PhD/pandas/pandas/core/frame.py in _dict_round(df, places)
   1455             for col in df:
   1456                 try:
-> 1457                     yield np.round(df[col], places[col])
   1458                 except KeyError:
   1459                     yield df[col]

/usr/local/lib/python2.7/dist-packages/numpy/core/fromnumeric.pyc in round_(a, decimals, out)
   2646     except AttributeError:
   2647         return _wrapit(a, 'round', decimals, out)
-> 2648     return round(decimals, out)
   2649 
   2650 

/home/rob/Dropbox/PhD/pandas/pandas/core/series.pyc in round(self, decimals, out)
   1209 
   1210         """
-> 1211         result = _values_from_object(self).round(decimals, out=out)
   1212         if out is None:
   1213             result = self._constructor(result,

TypeError: integer argument expected, got float