Bin continuous numerical data into discrete categorical intervals using Pandas pd.cut() and pd.qcut(). Transform numerical scores or prices into clean categories, define custom bin boundaries, apply text labels, and compare equal-width vs equal-frequency quantile binning.
pd.cut(): Bins values into equal-width intervals or custom defined ranges.pd.qcut(): Bins values into equal-frequency quantiles (e.g., quartiles, percentiles).import pandas as pd
df = pd.DataFrame({
"NAME": ["Ravi", "Raju", "Alex", "John", "Sara", "Priya"],
"SCORE": [35, 52, 68, 74, 88, 95]
})
print(df)
assert df.shape == (6, 2)
Expected output
NAME SCORE
0 Ravi 35
1 Raju 52
2 Alex 68
3 John 74
4 Sara 88
5 Priya 95
pd.cut() to divide the range between the minimum and maximum scores into equal-width segments.df["WIDTH_BIN"] = pd.cut(df["SCORE"], bins=3)
print(df[["NAME", "SCORE", "WIDTH_BIN"]])
assert df["WIDTH_BIN"].nunique() == 3
Expected output
NAME SCORE WIDTH_BIN
0 Ravi 35 (34.94, 55.0]
1 Raju 52 (34.94, 55.0]
2 Alex 68 (55.0, 75.0]
3 John 74 (55.0, 75.0]
4 Sara 88 (75.0, 95.0]
5 Priya 95 (75.0, 95.0]
bins and custom string category names to labels.bins = [0, 50, 75, 100]
labels = ["Fail", "Average", "Excellent"]
df["GRADE"] = pd.cut(df["SCORE"], bins=bins, labels=labels)
print(df[["NAME", "SCORE", "GRADE"]])
assert df.loc[0, "GRADE"] == "Fail" and df.loc[5, "GRADE"] == "Excellent"
Expected output
NAME SCORE GRADE
0 Ravi 35 Fail
1 Raju 52 Average
2 Alex 68 Average
3 John 74 Average
4 Sara 88 Excellent
5 Priya 95 Excellent
pd.qcut() to divide data into quantile-based bins containing an approximately equal number of sample observations per bin.df["TERTILE"] = pd.qcut(df["SCORE"], q=3, labels=["Low", "Medium", "High"])
print(df[["NAME", "SCORE", "TERTILE"]])
assert df["TERTILE"].value_counts().tolist() == [2, 2, 2]
Expected output
NAME SCORE TERTILE
0 Ravi 35 Low
1 Raju 52 Low
2 Alex 68 Medium
3 John 74 Medium
4 Sara 88 High
5 Priya 95 High
cut() versus qcut():
[18, 25, 38, 45, 62, 70] into 3 equal-frequency quantiles using pd.qcut() with labels ["Young", "Middle", "Senior"]. Verify that each bin contains exactly 2 customers.pd.qcut().ages = pd.Series([18, 25, 38, 45, 62, 70], name="AGE")
answer = pd.qcut(ages, q=3, labels=["Young", "Middle", "Senior"])
print(answer)
assert answer.value_counts().tolist() == [2, 2, 2]
Expected output
0 Young
1 Young
2 Middle
3 Middle
4 Senior
5 Senior
Name: AGE, dtype: category
Categories (3, object): ['Young' < 'Middle' < 'Senior']
Practice cut() and qcut() examples interactively directly in your browser:
Reference: Pandas cut() documentation and qcut() documentation.
Author & Instructor at plus2net
I write and maintain practical tutorials on Python, PHP, SQL, JavaScript, HTML, jQuery, and web development at plus2net. The tutorials focus on clear explanations, working examples, and code that readers can test and adapt while learning.