Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ENH: Using built-in round on a series #11763

Closed
Dr-Irv opened this issue Dec 4, 2015 · 8 comments · Fixed by #11809
Closed

ENH: Using built-in round on a series #11763

Dr-Irv opened this issue Dec 4, 2015 · 8 comments · Fixed by #11809
Labels
API Design Enhancement Numeric Operations Arithmetic, Comparison, and Logical operations
Milestone

Comments

@Dr-Irv
Copy link
Contributor

Dr-Irv commented Dec 4, 2015

Is there some philosophical reason that round(Series) and round(Dataframe) is not defined? See the example below. Being able to write round() as a function of a Dataframe or Series, as opposed to doing it afterwards would be nice. I'm willing to implement __round__() to make it work, but don't want to go down that path if there is some reason __round__() is not implemented.

Example:

    import pandas as pd
    import numpy as np
    df =  pd.DataFrame(np.random.randn(10, 3), columns=['A', 'B', 'C'])
    print (df.A.round())
    print (round(df))

Produces

0   -2
1    1
2   -1
3   -1
4    2
5    0
6    0
7    0
8   -2
9    0
Name: A, dtype: float64
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-8-9d2be9cbdc70> in <module>()
      3 df =  pd.DataFrame(np.random.randn(10, 3), columns=['A', 'B', 'C'])
      4 print (df.A.round())
----> 5 print (round(df))

TypeError: type DataFrame doesn't define __round__ method
@jreback
Copy link
Contributor

jreback commented Dec 4, 2015

sure you could define that to call the .round() method; do it in NDFrame (Panel will fail on this ATM so you could define .round(..) for that to call np.round(....), while Series/DataFrame have .round defined

@jreback jreback added this to the Next Major Release milestone Dec 4, 2015
@jreback jreback added the Numeric Operations Arithmetic, Comparison, and Logical operations label Dec 4, 2015
@srib
Copy link
Contributor

srib commented Dec 5, 2015

@jreback Series has .round supported. DataFrame doesn't seem to have one. Did you mean otherwise in your comment?

I would be happy to send a PR for this.

@jreback
Copy link
Contributor

jreback commented Dec 5, 2015

@srib
Copy link
Contributor

srib commented Dec 5, 2015

@jreback Thanks!

@Dr-Irv
Copy link
Contributor Author

Dr-Irv commented Dec 9, 2015

@jreback So I have something that works fine with Python 3, but Python 2 presents a problem because in Python 2, round(class) doesn't call class.round() . In other words, you can't easily override the built-in round() behavior in Python 2. I'm not sure of the best way to handle this. I could just avoid the round() test in the testing code when doing a Python 2 test and we don't worry about supporting round(DataFrame) with Python 2. Other suggestions welcome.

@jreback
Copy link
Contributor

jreback commented Dec 9, 2015

Python 2.7.10 |Continuum Analytics, Inc.| (default, Oct 19 2015, 18:31:17)
Type "copyright", "credits" or "license" for more information.

Obviously you wouldn't actually call object.__round__, but this works in py2.

In [3]: class F(float):
   ...:     def __round__(self):
   ...:         return object.__round__(self)
   ...:     

In [4]: F(5.2)
Out[4]: 5.2

In [5]: round(F(5.2))
Out[5]: 5.0

@Dr-Irv
Copy link
Contributor Author

Dr-Irv commented Dec 9, 2015

@jreback I don't think your example applies, because we want round(DataFrame) to work correctly, and your example worked OK because you were subclassing a float object. If you changed return object.__round__(self) to return 98, you'd see that. The issue is that in py2, round() calls float() and then does the rounding. py3 allows round() to be overridden on a class by implementing __round__() One can override float() by implementing __float__(), but I don't think we want to override the float() behavior for pandas. Found this article on stackoverflow related to this. http://stackoverflow.com/questions/9751476/float-and-round-in-python-2-and-3

@jreback
Copy link
Contributor

jreback commented Dec 9, 2015

@Dr-Irv ok, that IS an ugly hack. So just test this on PY3, that is fine. This is really just a convenience feature anyhow, it really breaks up the flow, but if people really want to use it then it would work e.g.

df.round(....) vs round(df)

@jreback jreback modified the milestones: 0.18.0, Next Major Release Dec 11, 2015
jreback added a commit that referenced this issue Dec 15, 2015
ENH: Using built-in round on a series #11763
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
API Design Enhancement Numeric Operations Arithmetic, Comparison, and Logical operations
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants