Skip to content

Dont do selection by callable if not wanted #13558

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

Closed
Chaoste opened this issue Jul 4, 2016 · 7 comments
Closed

Dont do selection by callable if not wanted #13558

Chaoste opened this issue Jul 4, 2016 · 7 comments
Labels
API Design Indexing Related to indexing on series/frames, not to indexes themselves
Milestone

Comments

@Chaoste
Copy link

Chaoste commented Jul 4, 2016

Copy-pastable Code Sample

import pandas as pd
import pandas.util.testing as tm

class myClass1:
    def __call__(self):
        return "Result 1"
    def __str__(self):
        return "Class 1"

class myClass2:
    def __call__(self):
        return "Result 2"
    def __str__(self):
        return "Class 2"

obj1 = myClass1()
obj2 = myClass2()
df = pd.DataFrame([], index=[0], columns=[obj1, obj2])
 # Throws error because new pandas version wants to select by callable
df[obj1] = obj1()
df[obj2] = obj2()

Expected Output

expected = pd.DataFrame([["Result 1", "Result 2"]], columns=[obj1, obj2])
tm.assert_frame_equal(df, expected)

How I fixed the test for the moment

class myClass1:
    def __call__(self, *args):
        if args:
            return self
        return "Result 1"
    def __str__(self):
        return "Class 1"

class myClass2:
    def __call__(self, *args):
        if args:
            return self
        return "Result 2"
    def __str__(self):
        return "Class 2"

If pandas invokes a callable object it passes the frame itself as a parameter. Because i dont need arguments for my call function i can prevent this call by checking if a argument is passed. Is there a better way of doing this or can you add an option so i can disable the new behavior.

output of pd.show_versions()

commit: None
python: 3.4.3.final.0
python-bits: 32
OS: Windows
OS-release: 8
machine: AMD64
processor: Intel64 Family 6 Model 60 Stepping 3, GenuineIntel
byteorder: little
LC_ALL: None
LANG: None

pandas: 0.18.1
nose: None
pip: 8.1.2
setuptools: 19.6.2
Cython: None
numpy: 1.11.0
scipy: 0.16.1
statsmodels: None
xarray: None
IPython: 4.2.0
sphinx: 1.4.1
patsy: None
dateutil: 2.5.3
pytz: 2016.4
blosc: None
bottleneck: None
tables: None
numexpr: None
matplotlib: 1.5.1
openpyxl: None
xlrd: None
xlwt: None
xlsxwriter: None
lxml: None
bs4: 4.4.1
html5lib: None
httplib2: None
apiclient: None
sqlalchemy: None
pymysql: None
psycopg2: None
jinja2: 2.8
boto: None
pandas_datareader: None
@sinhrks
Copy link
Member

sinhrks commented Jul 4, 2016

Thanks for the report. __setitem__ is now fixed not to apply callable. Can u check #13516 covers your use case?

@sinhrks sinhrks added Indexing Related to indexing on series/frames, not to indexes themselves Duplicate Report Duplicate issue or pull request API Design labels Jul 4, 2016
@jorisvandenbossche
Copy link
Member

jorisvandenbossche commented Jul 4, 2016

@sinhrks I don't think this is solved by that. The PR was to not execute the values that are stored (RHS, so to store callables in the dataframe), while here it is the key that should not be executed.

I don't think there is any solution for this. Pandas will never know whether a callable inside [] should be executed or should be used as label without executing (unless we provide an option to disable the executing of keys inside [])

@sinhrks sinhrks removed the Duplicate Report Duplicate issue or pull request label Jul 4, 2016
@jorisvandenbossche jorisvandenbossche added this to the 0.18.2 milestone Jul 4, 2016
@sinhrks
Copy link
Member

sinhrks commented Jul 4, 2016

Ah correct. I think options are:

  1. enclose _apply_if_callable with try-except
  2. check if key is a function, not callable class
  3. not support

Though using Index containing custom classes is not very performance efficient.

@jreback
Copy link
Contributor

jreback commented Jul 4, 2016

I guess option 1 is fine or just close as non supported

this is abuse of pandas by passing in callables that behave differently with args or not - very odd, and not idiomatic nor pythonic

honestly just close and user beware (unless it's a trivial fix)

@sinhrks
Copy link
Member

sinhrks commented Jul 4, 2016

@jreback it's true, added option 3 (not support)

CC @jorisvandenbossche @shoyer

@shoyer
Copy link
Member

shoyer commented Jul 5, 2016

I would pick the "not support" option 3. Adding complex logic to attempt to fall back gracefully here would be un-Pythonic.

@jorisvandenbossche
Copy link
Member

I would also vote to not do any additional work in pandas to support this.
@Chaoste you can of course keep using your current workaround (checking the args)

@jreback jreback closed this as completed Jul 5, 2016
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
API Design Indexing Related to indexing on series/frames, not to indexes themselves
Projects
None yet
Development

No branches or pull requests

5 participants