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

BUG: Using NamedTuples with .iloc fails #48188

Open
3 tasks done
tomaarsen opened this issue Aug 21, 2022 · 3 comments
Open
3 tasks done

BUG: Using NamedTuples with .iloc fails #48188

tomaarsen opened this issue Aug 21, 2022 · 3 comments
Assignees
Labels
Bug Indexing Related to indexing on series/frames, not to indexes themselves

Comments

@tomaarsen
Copy link
Contributor

Pandas version checks

  • I have checked that this issue has not already been reported.

  • I have confirmed this bug exists on the latest version of pandas.

  • I have confirmed this bug exists on the main branch of pandas.

Reproducible Example

import pandas as pd
import numpy as np

# A df with two level MultiIndex
df = pd.DataFrame(np.arange(120).reshape(6, -1))

# Indexing with a normal tuple works as expected:
# normal subset
print(df.iloc[1, 2])  # <- Works
print(df.iloc[(1, 2)])  # <- Works

# Now the same with a named tuple
from collections import namedtuple

indexer_tuple = namedtuple("Indexer", ["x", "y"])

# simple subset with named tuple
print(df.iloc[indexer_tuple(x=1, y=2)])  # <- Does not work
# Raises:
# TypeError: Cannot index by location index with a non-integer key
# Converting to a tuple works again
print(df.iloc[tuple(indexer_tuple(x=1, y=2))])  # <- Works

Issue Description

The output of the prior snippet is:

22
22
Traceback (most recent call last):
  File "/workspaces/pandas/#48124.py", line 19, in <module>
    print(df.iloc[indexer_tuple(x=1, y=2)])  # <- Does not work
  File "/workspaces/pandas/pandas/core/indexing.py", line 1074, in __getitem__
    return self._getitem_axis(maybe_callable, axis=axis)
  File "/workspaces/pandas/pandas/core/indexing.py", line 1620, in _getitem_axis
    raise TypeError("Cannot index by location index with a non-integer key")
TypeError: Cannot index by location index with a non-integer key

In short, indexing (with iloc) works with a tuple, but not with a namedtuple.
This issue also persists when using MultiIndex.

See #48124 for a similar issue.

cc @phofl

Expected Behavior

I would expect indexing with a namedtuple to produce the same results as a regular tuple. In short, I would expect the code above to produce:

22
22
22
22

Installed Versions

INSTALLED VERSIONS

commit : 221f636
python : 3.8.13.final.0
python-bits : 64
OS : Linux
OS-release : 5.4.72-microsoft-standard-WSL2
Version : #1 SMP Wed Oct 28 23:40:43 UTC 2020
machine : x86_64
processor : x86_64
byteorder : little
LC_ALL : C.UTF-8
LANG : C.UTF-8
LOCALE : en_US.UTF-8

pandas : 1.5.0.dev0+1349.g221f6362bc
numpy : 1.22.4
pytz : 2022.2.1
dateutil : 2.8.2
setuptools : 65.0.2
pip : 22.2.2
Cython : 0.29.32
pytest : 7.1.2
hypothesis : 6.47.1
sphinx : 4.5.0
blosc : None
feather : None
xlsxwriter : 3.0.3
lxml.etree : 4.9.1
html5lib : 1.1
pymysql : 1.0.2
psycopg2 : 2.9.3
jinja2 : 3.0.3
IPython : 8.4.0
pandas_datareader: 0.10.0
bs4 : 4.11.1
bottleneck : 1.3.5
brotli :
fastparquet : 0.8.1
fsspec : 2022.7.1
gcsfs : 2022.7.1
matplotlib : 3.5.3
numba : 0.55.2
numexpr : 2.8.3
odfpy : None
openpyxl : 3.0.9
pandas_gbq : 0.17.6
pyarrow : 8.0.1
pyreadstat : 1.1.9
pyxlsb : 1.0.9
s3fs : 0.6.0
scipy : 1.9.0
snappy :
sqlalchemy : 1.4.40
tables : 3.7.0
tabulate : 0.8.10
xarray : 2022.6.0
xlrd : 2.0.1
xlwt : 1.3.0
zstandard : 0.18.0
tzdata : None

@tomaarsen tomaarsen added Bug Needs Triage Issue that has not been reviewed by a pandas team member labels Aug 21, 2022
@rhshadrach rhshadrach added Indexing Related to indexing on series/frames, not to indexes themselves Needs Discussion Requires discussion from core team before further action and removed Needs Triage Issue that has not been reviewed by a pandas team member labels Jan 13, 2024
@rhshadrach
Copy link
Member

Thanks for the report. Looks like this is due to

if type(key) is tuple:

That check goes back at least 11 years, and likely we should be using isinstance instead. Further investigations and PRs to fix are welcome.

@rhshadrach rhshadrach added good first issue and removed Needs Discussion Requires discussion from core team before further action labels Jan 13, 2024
@EltonGohJH
Copy link

Can I give this a try?

@Deadlica
Copy link

Deadlica commented Mar 3, 2024

take

Deadlica added a commit to NoelMT/pandas-noelmt that referenced this issue Mar 3, 2024
- unit test for added for test_iloc.py that verifies that all four uses of iloc given in the reproducible example now works
Deadlica added a commit to NoelMT/pandas-noelmt that referenced this issue Mar 3, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment