How to Solve "TypeError: reduction operation 'argmax' not allowed for this dtype" in Pandas
The TypeError: reduction operation 'argmax' not allowed for this dtype
in Pandas arises when you attempt to use functions like idxmax()
, argmax()
, idxmin()
, or argmin()
on columns that don't contain numeric data.
This guide explains the common causes of this error and provides solutions using pandas.to_numeric()
and DataFrame.astype()
to ensure your data is in the correct format.
Understanding the Error
The idxmax()
, argmax()
, idxmin()
, and argmin()
methods are designed to find the index or position of the maximum or minimum value in a numeric column. If the DataFrame column's data type is object
(often representing strings), these operations can not be performed, resulting in the TypeError
.
import pandas as pd
df = pd.DataFrame({
'experience': ['5', '14', '7', '10'],
'salary': [175.1, 180.2, 190.3, 205.4],
}, index=['Alice', 'Bob', 'Carl', 'Dan'])
print(df.dtypes)
print(df.idxmax()) # TypeError: reduction operation 'argmax' not allowed for this dtype
Output:
experience object
salary float64
dtype: object
Traceback (most recent call last):
File "main.py", line 9, in <module>
print(df.idxmax())
File "/usr/lib/python3.8/site-packages/pandas/core/frame.py", line 8861, in idxmax
indices = nanops.nanargmax(self.values, axis=axis, skipna=skipna)
File "/usr/lib/python3.8/site-packages/pandas/core/nanops.py", line 66, in _f
raise TypeError(
TypeError: reduction operation 'argmax' not allowed for this dtype
- The error occurs because the first column contains object datatypes (strings) while the salary column contains floats.
- Since strings are not directly comparable this will throw an exception.
Solutions
To solve this, convert the non-numeric columns to a numeric type before calling the desired method.
Converting Columns to Numeric with pandas.to_numeric()
The pandas.to_numeric()
method is the most flexible way to convert a column to a numeric type:
import pandas as pd
df = pd.DataFrame({
'experience': ['5', '14', '7', '10'],
'salary': [175.1, 180.2, 190.3, 205.4],
}, index=['Alice', 'Bob', 'Carl', 'Dan'])
df['experience'] = pd.to_numeric(df['experience']) # Convert 'experience' to numeric
print(df.dtypes)
print(df.idxmax()) # Now it will execute
Output:
experience int64
salary float64
dtype: object
experience Bob
salary Dan
dtype: object
- The example converts all strings to int64, and then proceeds to call
idxmax
function, which works as expected now.
Converting All Object Columns to Numeric
To convert all object columns in the DataFrame you can use a for loop.
First use eq()
with object
to select the columns.
import pandas as pd
df = pd.DataFrame({
'experience': ['5', '14', '7', '10'],
'another': ['1', '3', '14', '5'],
'salary': [175.1, 180.2, 190.3, 205.4],
}, index=['Alice', 'Bob', 'Carl', 'Dan'])
object_columns = df.columns[df.dtypes.eq(object)]
print(object_columns)
# Output: Index(['experience', 'another'], dtype='object')
df[object_columns] = df[object_columns].apply(
pd.to_numeric,
errors='coerce',
axis=0
)
print(df.idxmax())
Output:
Index(['experience', 'another'], dtype='object')
experience Bob
another Carl
salary Dan
dtype: object
- The dtypes attribute gets the type of every column in the dataframe.
- The
DataFrame.apply
is called to map all of the strings from all columns to numbers, throwingerrors='coerce'
to avoid theValueError
if a specific column contains strings that are not numeric.
Using DataFrame.astype()
The DataFrame.astype()
method is another way to convert the columns to numeric types.
import pandas as pd
df = pd.DataFrame({
'experience': ['5', '14', '7', '10'],
'salary': [175.1, 180.2, 190.3, 205.4],
}, index=['Alice', 'Bob', 'Carl', 'Dan'])
df['experience'] = df['experience'].astype(int) # Explicitly cast to integer
print(df.idxmax())
Output:
experience Bob
salary Dan
dtype: object
- The call to
DataFrame.astype(int)
converts the columns into anint
type.
Checking Data Types
Before calling any numerical operations such as idxmax
, always check the datatypes of your DataFrame columns using df.dtypes
:
import pandas as pd
df = pd.DataFrame({
'experience': ['5', '14', '7', '10'],
'salary': [175.1, 180.2, 190.3, 205.4],
}, index=['Alice', 'Bob', 'Carl', 'Dan'])
print(df.dtypes) # Displays the data type of each column
Output:
experience object
salary float64
dtype: object
This helps identify columns that need conversion.
Conclusion
The TypeError: reduction operation 'argmax' not allowed for this dtype
in Pandas is easily resolved by ensuring your data is in the correct numeric format before performing the method calls.
- The most reliable way to do this is to use
pandas.to_numeric()
to convert values and handle any potential bad data. - Use
df.dtypes
to check that your columns have been properly converted.