Introduction
ValueError: Can only tuple-index with a MultiIndex
This exception is raised when trying to tuple-index a MultiIndex with something other than another MultiIndex or a list/tuple of valid keys.
If you have a MultiIndex and want to tuple-index it with something else, you need to use the .get_loc() method:
mi.get_loc((‘foo’, ‘bar’))
# this would be the label for row 0
mi.get_loc((‘baz’, ‘qux’))
# this would be the label for row 1
What is a ValueError?
ValueError is a built-in Python exception that’s raised when a program encounters an invalid value. This usually happens when you try to use a data type incorrectly. For example, you might try to use a string where an integer is expected.
What Causes a ValueError?
There are many potential causes for a ValueError, but the most common cause is that you are trying to tuple-index an object with a non-tuple indexer.
For example, consider the following code:
import pandas as pd
df = pd.DataFrame({'col1': [1, 2], 'col2': [3, 4]})
df['col1'] # this works fine
df[0] # this will raise a ValueError
The reason this raises a ValueError is because df['col1']
returns a Series
object, which can be tuple-indexed by an integer indexer (e.g. 0
), but not by a non-tuple indexer (e.g. 'col1'
). In contrast, df[0]
returns a DataFrame
object, which can be tuple-indexed by a tuple indexer (e.g. ('col1', 'col2')
), but not by a non-tuple indexer (e.g. 0
).
There are other potential causes for a ValueError, but this is the most common one. If you encounter a ValueError and you’re not sure why it’s happening, feel free to post a question on StackOverflow with your code and the full traceback and someone will be able to help you out.
How to Fix a ValueError
A ValueError occurs when you try to access a tuple index that does not exist. In other words, you are trying to access a non-existent element in the tuple. This can happen when you are indexing a tuple with an integer that is too large. For example, if you have a tuple with three elements and you try to access the fourth element, you will get a ValueError.
There are two ways to fix this error. The first is to make sure that you are indexing the tuple with a valid integer. The second is to use the .get() method to retrieve the element from the tuple.
To fix the first issue, make sure that you are indexing the tuple with a valid integer:
tuple = (1, 2, 3)
Valid indexes
print(tuple[0])
print(tuple[1])
print(tuple[2])
Invalid index (returns ValueError)
print(tuple[3])
To fix the second issue, use the .get() method to retrieve the element from the tuple:
tuple = (1, 2, 3)
Valid indexes
print(tuple.get(0)) # 1st element in tuple – same as using tuple[0] – will return 1 from print statement using .get method retunrs value as required per documentation for get method for tuples but this example uses int 0 as arguement for get method whereas original question uses string ‘zero’ as arguement which would return ‘None’ based on python documenation for get methos for tuples since there is no key inputed in form of an int or string as ‘zero’ which would then return default value of ‘None’ since there was no inputted key arguement match found per python documentation for get method on tuples so this answer just replaces string input of ‘zero’ with int input of 0 based on python documenation requirements for inputting a key arguement for .get() methods where key arguements can be either strings or integers per python documenation )
https://docs.python.org/3/library/stdtypes.html#tuples – section 7 .7 Tuples and Sequences has information about .get() methods
Conclusion
If you receive the error “ValueError: can only tuple-index with a MultiIndex”, it means that you are trying to index your DataFrame with a tuple, but the DataFrame does not have a MultiIndex.
A MultiIndex is a type of index that allows you to index your data with more than one column. For example, if you have a DataFrame with two columns (‘A’ and ‘B’), you could create a MultiIndex with columns (‘A’, ‘B’).
If you don’t have a MultiIndex, you can still index your DataFrame with tuples, but you’ll need to use the .loc[] method instead of [] (i.e., df.loc[(1,2)] instead of df[(1,2)]).