Skip to content

Index.map fails when index has a name and mapping returns tuple #20990

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
willvousden opened this issue May 9, 2018 · 5 comments · Fixed by #29093
Closed

Index.map fails when index has a name and mapping returns tuple #20990

willvousden opened this issue May 9, 2018 · 5 comments · Fixed by #29093
Labels
good first issue Needs Tests Unit test(s) needed to prevent regressions
Milestone

Comments

@willvousden
Copy link

willvousden commented May 9, 2018

This is related to #18696.

Code Sample

import pandas as pd
import numpy as np

count = 6
index = pd.date_range('2018-01-01', periods=count, freq='M')

a = pd.Series(np.arange(count), index=index)
a.index.name = 'name' # This causes the failure.

b = a.copy()
b.index = a.index.map(lambda x: (x.year, x.month))
print(b)

Problem description

The above code fails with ValueError: Names should be list-like for a MultiIndex.

I understand that a scalar name can't meaningfully be carried over to a MultiIndex, but there's no documentation stating that Index.map will fail under these conditions, and moreover there's no way to use Index.map here without either

  1. modifying the source index in-place to remove its name, which is destructive, or
  2. creating a temporary copy in order to set name to None, which is wasteful.

I think a better solution would be to discard the name when returning a MultiIndex if the existing name isn't compatible, and then to make this behaviour clear in the documentation.

Expected Output

2018  1    0
      2    1
      3    2
      4    3
      5    4
      6    5
dtype: int64

Output of pd.show_versions()

INSTALLED VERSIONS
------------------
commit: None
python: 3.5.2.final.0
python-bits: 64
OS: Linux
OS-release: 4.4.0-119-generic
machine: x86_64
processor: x86_64
byteorder: little
LC_ALL: None
LANG: en_US.UTF-8
LOCALE: en_US.UTF-8

pandas: 0.22.0
pytest: None
pip: 10.0.1
setuptools: 39.1.0
Cython: None
numpy: 1.14.3
scipy: None
pyarrow: None
xarray: None
IPython: None
sphinx: None
patsy: None
dateutil: 2.7.2
pytz: 2018.4
blosc: None
bottleneck: None
tables: None
numexpr: None
feather: None
matplotlib: None
openpyxl: None
xlrd: None
xlwt: None
xlsxwriter: None
lxml: None
bs4: None
html5lib: None
sqlalchemy: None
pymysql: None
psycopg2: None
jinja2: None
s3fs: None
fastparquet: None
pandas_gbq: None
pandas_datareader: None

@willvousden
Copy link
Author

willvousden commented May 9, 2018

In fact, perhaps a better solution would be to add a names= parameter to Index.map!

@VincentLa
Copy link
Contributor

I was playing around with this and discovered that

a.index.name = ['name', 'name']

works. In particular,

import pandas as pd
import numpy as np

count = 6
index = pd.date_range('2018-01-01', periods=count, freq='M')

a = pd.Series(np.arange(count), index=index)
a.index.name = ['name', 'name'] # This now works.

b = a.copy()
b.index = a.index.map(lambda x: (x.year, x.month))
b

returns

2018  1       0
      2       1
      3       2
      4       3
      5       4
      6       5
dtype: int64

@mroeschke
Copy link
Member

This looks to be working; could use a test:

In [19]: import pandas as pd
    ...: import numpy as np
    ...:
    ...: count = 6
    ...: index = pd.date_range('2018-01-01', periods=count, freq='M')
    ...:
    ...: a = pd.Series(np.arange(count), index=index)
    ...: a.index.name = 'name'
    ...:
    ...: b = a.copy()
    ...: b.index = a.index.map(lambda x: (x.year, x.month))

In [20]: b
Out[20]:
name  name
2018  1       0
      2       1
      3       2
      4       3
      5       4
      6       5
dtype: int64

@mroeschke mroeschke added good first issue Needs Tests Unit test(s) needed to prevent regressions labels Jan 13, 2019
@Reksbril
Copy link
Contributor

Can I work on this? I'm first time contributor and would like to get into the project.

@mroeschke
Copy link
Member

Go for it @Reksbril!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
good first issue Needs Tests Unit test(s) needed to prevent regressions
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants