TypeError: > not supported between instances of float and str in Scikit-Learn
Clean mixed-type columns with .astype(str) or process numerical and categorical features separately using ColumnTransformer.
Root Cause Analysis
This error occurs when Python tries to sort or fit categorical transformer classes (like LabelEncoder or OrdinalEncoder) on a column containing mixed data types (such as both strings and floating-point NaN values).
1. Comparison Protocol in Transformers
When LabelEncoder.fit() is called, it sorts unique classes internally using Python's native < and > comparison operators to establish a deterministic integer mapping. In Python 3, comparing a str directly to a float (such as np.nan) is illegal and raises TypeError: '>' not supported between instances of 'float' and 'str'.
2. The Missing Value Trap in Text Columns
When pandas reads CSV files with empty cells in text columns, it fills missing entries with np.nan (a float) by default. The resulting column has object dtype containing both string labels ('Paris', 'London') and float values (NaN), which crashes LabelEncoder.
3. Resolving Mixed Types
Cast the entire column to string with df['col'].astype(str) or fill missing values before encoding with df['col'].fillna('Missing').
4. Using OrdinalEncoder for Features
Remember that LabelEncoder is intended exclusively for 1D target labels y. For feature matrices X, always use OrdinalEncoder or OneHotEncoder within a ColumnTransformer.
Reproduction Code (MCVE)
import numpy as np
from sklearn.preprocessing import LabelEncoder
# Mixed-type array containing both strings and floats (np.nan)
mixed_labels = np.array(['cat', 1.5, 'dog'], dtype=object)
le = LabelEncoder()
# TypeError: '<' not supported between instances of 'float' and 'str'
le.fit(mixed_labels)
Solution 1: Cast Array to Uniform String Dtype
Convert all elements in the column or array to homogeneous strings before fitting the encoder.
import numpy as np
from sklearn.preprocessing import LabelEncoder
mixed_labels = np.array(['cat', 1.5, 'dog'], dtype=object)
# Convert all items to clean strings
clean_labels = mixed_labels.astype(str)
le = LabelEncoder()
encoded = le.fit_transform(clean_labels)
print('Encoded classes:', le.classes_)
print('Encoded output:', encoded)
Solution 2: Handle Missing Categories via SimpleImputer & OrdinalEncoder
Use SimpleImputer with a constant placeholder before categorical encoding in a structured Pipeline.
import numpy as np
from sklearn.impute import SimpleImputer
from sklearn.preprocessing import OrdinalEncoder
from sklearn.pipeline import make_pipeline
X_raw = np.array([['red'], [np.nan], ['blue']], dtype=object)
pipeline = make_pipeline(
SimpleImputer(strategy='constant', fill_value='missing'),
OrdinalEncoder()
)
encoded = pipeline.fit_transform(X_raw)
print('Pipeline encoded output:', encoded)
A common mistake is using LabelEncoder on 2D feature matrices X, which causes shape errors and mixed-type sorting failures. LabelEncoder is strictly designed for 1D target vectors y. Use OneHotEncoder or OrdinalEncoder for features X. Contrast this TypeError with TypeError: '<' not supported between instances of 'str' and 'int'. Always check column types using df.dtypes and verify df.isna().sum() during preprocessing.