You should convert your column to a float and use float("inf") instead of "Inf":

import pandas as pd

df["Discretized"] = pd.cut(x=df["Amount"].astype(float), bins=[0,2,200,float('inf')], labels=["Low","Medium","Large"])

-----------------------------------------------
    Amount  Discretized
0   216.00  Large
1   30.00   Medium
2   30.00   Medium
3   36.00   Medium
4   25.00   Medium
5   38.00   Medium
6   78.8    Medium
7   189.00  Medium
8   43.00   Medium
9   110.00  Medium
-----------------------------------------------
Answer from ko3 on Stack Overflow
🌐
scikit-learn
scikit-learn.org › stable › auto_examples › preprocessing › plot_discretization.html
Using KBinsDiscretizer to discretize continuous features — scikit-learn 1.9.0 documentation
Compared with the result before discretization, linear model become much more flexible while decision tree gets much less flexible. Note that binning features generally has no beneficial effect for tree-based models, as these models can learn to split up the data anywhere.
🌐
Dagster
dagster.io › glossary › data-discretization
What Does Discretize Mean | Dagster
One practical example of discretization in Python is using the pandas cut() function. The cut() function allows you to specify the number of bins you want to use and the range of the data, and it returns a new column with the values binned into those intervals.
🌐
DataCamp
campus.datacamp.com › courses › introduction-to-predictive-analytics-in-python › interpreting-and-explaining-models
Discretization of continuous variables | Python
The first step of creating predictor insight graphs is to discretize the continuous variables. In python, you can easily discretize pandas columns using the `qcut` method. Assume that you want to divide the variable maximum gift in three bins of equal size. Then you can use the `qcut` method ...
🌐
Towards Data Science
towardsdatascience.com › home › latest › an intro to discretization techniques for machine learning
An Intro to Discretization Techniques for Machine Learning | Towards Data Science
March 5, 2025 - Equal frequency discretization entails transforming continuous data into bins, with each bin having the same (or similar) number of records. To carry out this method in Python, we can use the scikit-learn package’s KBinsDiscretizer, where the strategy hyperparameter is set to ‘quantile’.
🌐
Packtpub
subscription.packtpub.com › book › data › 9781838552862 › 1 › ch01lvl1sec09 › data-discretization
Introduction to Data Science and Data Pre-Processing | Data Science with Python[Instructor Edition]
The main challenge in discretization is to choose the number of intervals or bins and how to decide on their width. Here we make use of a function called pandas.cut(). This function is useful to achieve the bucketing and sorting of segmented data.
Find elsewhere
🌐
Kaggle
kaggle.com › code › mrbisht › discretization-continuous-variables
Discretization Continuous Variables | Kaggle
September 18, 2022 - Explore and run AI code with Kaggle Notebooks | Using data from Spaceship Titanic
🌐
Medium
medium.com › @gmshakil786 › mastering-discretization-in-data-science-a-step-by-step-guide-with-python-and-sklearn-examples-42d20676d458
Mastering Discretization in Data Science: A Step-by-Step Guide with Python and sklearn Examples | by Shakil Ur Rehman | Medium
September 21, 2025 - As a Data Scientist, I’ll guide you through implementing discretization using scikit-learn (sklearn) in Python, step by step. I’ll explain how to use the KBinsDiscretizer class, which is sklearn’s primary tool for discretization, and provide a clear example with code.
Top answer
1 of 1
2

The error message is not too hard. The pandas cut method demands that the cut vector [0,x1,x2,x3,100] is strictly monotinic. By having some mechanism to make sure that no invalid values are passed to the cut function, we are safe. That is what I implemented below. To denote an invalid setting, it is customary to use np.inf since all other values are lower. Therefore, every minizmier would say such an invalid is undesirable as a solution. See below for the implementation. I also included all the imports and some data generation, so that it is simple to use the code. Please do so in future questions as well.

You might want to use more than 10 bins per dimension in the brute force search.

Also - the code is quite inefficient. Since it brute forces over all combinations of x1, x2, x3, but a lot of them are invalid (e.g. x2<=x1), you might want to parametrize the problem in (x1,x2-x1, x3-x2) instead, and search over nonnegative values in the second and third component.

Finally, the brute method is a minimizer, so you should return -cohen_kappa from the objective

#%%
import numpy as np
from sklearn.metrics import cohen_kappa_score, confusion_matrix
from scipy.stats import truncnorm
import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt
from scipy.optimize import brute

#
# Generate Data
#
n = 1000
np.random.seed(0)
y = np.random.choice(4, p=[0.1, 0.3, 0.4, 0.2], size=n)
x = np.zeros(n)
for i in range(5):
    low = 0
    high = 100
    mymean = 20 * i
    myscale = 8
    a, b = (low - mymean) / myscale, (high - mymean) / myscale
    x[y == i] = truncnorm.rvs(a=a, b=b, loc=mymean, scale=myscale, size=np.sum(y == i))
data = pd.DataFrame({"cont_attribute": x, "class_label": y})

# make a loss function that accounts for the bad orderings
def loss(cuts):
    x1, x2, x3 = cuts
    if 0 >= x1 or x1 >= x2 or x2 >= x3 or x3 >= 100:
        return np.inf
    yhat = pd.cut(
        data["cont_attribute"],
        bins=[0, x1, x2, x3, 100],
        labels=[0, 1, 2, 3],
        # duplicates="drop",
    ).astype("int")
    return -cohen_kappa_score(data["class_label"], yhat)


# Compute the result via brute force
ranges = [(0, 100)] * 3
Ns=30
result = brute(func=loss, ranges=ranges, Ns=Ns)
print(result)
print(-loss(result))

# Evaluate the final result in a confusion matrix
x1, x2, x3 = result
data["class_pred"] = pd.cut(
    data["cont_attribute"],
    bins=[0, x1, x2, x3, 100],
    labels=[0, 1, 2, 3],
    duplicates="drop",
).astype("int")
mat = confusion_matrix(y_true=data['class_label'],y_pred=data['class_pred'])
plt.matshow(mat)
# Loop over data dimensions and create text annotations.
for i in range(4):
    for j in range(4):
        text = plt.text(j, i, mat[i, j],
                       ha="center", va="center", color="grey")
plt.xlabel('Predicted class')
plt.ylabel('True class')
plt.show()

# Evaluate result graphically
# inspect the data
fig,ax = plt.subplots(2,1)
sns.histplot(data=data, x="cont_attribute", hue="class_label",ax=ax[0],multiple='stack')
sns.histplot(data=data, x="cont_attribute", hue="class_pred",ax=ax[1],multiple='stack')
plt.show()

Regarding the use of scipy.optimize.minimize, that is not possible when using the cohen kappa as a ojective. Since it is not differentiable, it is not so easy to optimize over. Consider using a cross entropy loss function instead. But in that case, you would need a (parametric) model for the classification task.

A standard ordinal classifier is available in the ordinal regression package in statsmodels. It will be vastly faster than the brute method, but possibly less accurate when evaluated on cohen kappa. Going that route is probably what I would have done if going for a higher number of bins.

🌐
The Security Buddy
thesecuritybuddy.com › home › data preprocessing › how to perform equal width discretization using python pandas?
How to perform equal width discretization using Python pandas? - The Security Buddy
November 16, 2022 - We can use the pandas.cut() function to discretize a numerical variable into equal-sized buckets. For example, let’s read the diamonds dataset and discretize the numerical values in the price column of the dataset. We can use the following Python code for that purpose:
Top answer
1 of 5
12

Update (Sep 2018): As of version 0.20.0, there is a function, sklearn.preprocessing.KBinsDiscretizer, which provides discretization of continuous features using a few different strategies:

  • Uniformly-sized bins
  • Bins with "equal" numbers of samples inside (as much as possible)
  • Bins based on K-means clustering

Unfortunately, at the moment, the function does not accept custom intervals (which is a bummer for me as that is what I wanted and the reason I ended up here). If you want to achieve the same, you can use Pandas function cut:

import numpy as np
import pandas as pd
n_samples = 10
a = np.random.randint(0, 10, n_samples)

# say you want to split at 1 and 3
boundaries = [1, 3]
# add min and max values of your data
boundaries = sorted({a.min(), a.max() + 1} | set(boundaries))

a_discretized_1 = pd.cut(a, bins=boundaries, right=False)
a_discretized_2 = pd.cut(a, bins=boundaries, labels=range(len(boundaries) - 1), right=False)
a_discretized_3 = pd.cut(a, bins=boundaries, labels=range(len(boundaries) - 1), right=False).astype(float)
print(a, '\n')
print(a_discretized_1, '\n', a_discretized_1.dtype, '\n')
print(a_discretized_2, '\n', a_discretized_2.dtype, '\n')
print(a_discretized_3, '\n', a_discretized_3.dtype, '\n')

which produces:

[2 2 9 7 2 9 3 0 4 0]

[[1, 3), [1, 3), [3, 10), [3, 10), [1, 3), [3, 10), [3, 10), [0, 1), [3, 10), [0, 1)]
Categories (3, interval[int64]): [[0, 1) < [1, 3) < [3, 10)]
 category

[1, 1, 2, 2, 1, 2, 2, 0, 2, 0]
Categories (3, int64): [0 < 1 < 2]
 category

[1. 1. 2. 2. 1. 2. 2. 0. 2. 0.]
 float64

Note that, by default, pd.cut returns a pd.Series object of dtype Category with elements of type interval[int64]. If you specify your own labels, the dtype of the output will still be a Category, but the elements will be of type int64. If you want the series to have a numeric dtype, you can use .astype(np.int64).

My example uses integer data, but it should work just as fine with floats.

2 of 5
10

The answer is no. There is no binning in scikit-learn. As eickenberg said, you might want to use np.histogram. Features in scikit-learn are assumed to be continuous, not discrete. The main reason why there is no binning is probably that most of sklearn is developed on text, image featuers or dataset from the scientific community. In these settings, binning is rarely helpful. Do you know of a freely available dataset where binning is really beneficial?

🌐
PythonProg
pythonprog.com › home › data discretization in machine learning (with python examples)
Data Discretization in Machine Learning (with Python Examples) | PythonProg
December 12, 2023 - According to Wikipedia, “Data ... binning, is the process of converting a continuous variable into a categorical or discrete variable by dividing the entire range of the variable into a set of intervals or bins.” In other ...
🌐
Medium
trainindata.medium.com › variable-discretization-in-machine-learning-7b09009915c2
Variable Discretization in Machine Learning | Medium
October 20, 2022 - We can carry out equal-frequency discretization in Python using the open source library Feature-engine.
🌐
LearnModernPython
learnmodernpython.com › home › pandas and data discretization: a beginner’s guide to categorizing continuous data
Pandas And Data Discretization: A Beginner's Guide To Categorizing Continuous Data
February 17, 2026 - You’ll also need a suitable environment to run your Python code. Jupyter Notebook, Google Colab, or any other Python IDE will work perfectly. Pandas provides two primary functions for discretization: `pd.cut()`: This function allows you to discretize data into bins of equal length or custom bins defined by you.
🌐
Medium
medium.com › @kelvinsang97 › binning-bucketing-discretization-in-python-be665936a090
Binning/Bucketing/Discretization in Python | by Kelvin Kipsang | Medium
January 3, 2023 - Binning/Bucketing/Discretization in Python Data binning is a common preprocessing technique used to group intervals of continuous data into “bins” or “buckets”. Grouping data in bins (or …
🌐
Stack Overflow
stackoverflow.com › questions › 70058128 › how-to-discretize-a-datetime-column
python - How to discretize a datetime column? - Stack Overflow
import pandas as pd from datetime import datetime # make dataframe df = pd.DataFrame({ 'started_at': ['14:20:56', '00:13:24', '16:01:33'] }) # convert column to datetime df['started_at'] = pd.to_datetime(df['started_at']) # make day indicator column df['day'] = df['started_at'].apply(lambda ts: 1 if ts.hour > 12 else 0) # make indicator column for every ten minutes for i in range(24): for j in range(6): col = 'hour_' + str(i) + '_min_' + str(j) + '0' df[col] = df['started_at'].apply(lambda ts: 1 if int(ts.minute/10) == j and ts.hour == i else 0) print(df)