pandas-dev/pandas · error · TypeError
bins argument only works with numeric data.
Error message
bins argument only works with numeric data.
What it means
The value_counts() method accepts a bins parameter to group values into equal-width numeric intervals before counting. Internally it delegates to pd.cut(), which requires numeric data to define interval edges. When the underlying values are non-numeric (strings, datetimes that cannot be binned, categorical, etc.), cut() raises a TypeError that is caught and re-raised with this clearer message.
Solutions
- Remove the bins parameter for non-numeric columns: df['col'].value_counts().
- Convert the column to numeric first: pd.to_numeric(df['col'], errors='coerce').value_counts(bins=5).
- Check the dtype before applying bins: if df['col'].dtype.kind in 'iufc': df['col'].value_counts(bins=5) else: df['col'].value_counts().
Example fix
# before df['category'].value_counts(bins=5) # after df['category'].value_counts() # no binning for categorical data
Defensive patterns
Strategy: validation
Validate before calling
def safe_value_counts(series, bins=None):
if bins is not None and series.dtype.kind not in 'iufcb':
# integer, unsigned, float, complex, boolean
raise TypeError(
f"bins requires numeric data, got dtype {series.dtype}"
)
return series.value_counts(bins=bins) Type guard
def is_numeric_for_bins(series) -> bool:
return series.dtype.kind in 'iufcb' Try / catch
try:
result = df['col'].value_counts(bins=5)
except TypeError as e:
if "bins argument" in str(e):
result = df['col'].value_counts() # fall back without bins
else:
raise Prevention
- Check df['col'].dtype.kind before passing bins to value_counts.
- Use df.select_dtypes(include='number') to filter before applying bins-based value_counts.
- Build a dtype-aware utility that skips bins for non-numeric columns.
When it happens
Trigger: Calling df['category_column'].value_counts(bins=5) on a string or object-dtype column. Calling Series.value_counts(bins=10) on a boolean or timedelta column that cut() cannot bin. Passing bins to value_counts on categorical data.
Common situations: Applying a generic value_counts(bins=N) template across mixed-type DataFrame columns without checking dtype first. Processing a column that was expected to be numeric but contains string representations of numbers or mixed types. Reusing analysis code from a numeric pipeline on a text-heavy dataset.
Related errors
- has no 'diff' method. Convert to a suitable dtype prior to…
- Array with ndim > 2 is not supported.
- ArrowStringArray requires a PyArrow (chunked) array of…
- bad operand type for unary +
- Can only use the '.sparse' accessor with Sparse data.
AI-assisted analysis of pandas-dev/pandas@3b7651241d (2026-08-11).
Data as JSON: /api/errors/0e136acb57f1ae64.
Report an issue: GitHub.
Appendix: source
Thrown at pandas/core/algorithms.py:1021
DatetimeIndex,
Index,
Series,
TimedeltaIndex,
)
index_name = getattr(values, "name", None)
name = "proportion" if normalize else "count"
if bins is not None:
from pandas.core.reshape.tile import cut
if isinstance(values, Series):
values = values._values
try:
ii = cut(values, bins, include_lowest=True)
except TypeError as err:
raise TypeError("bins argument only works with numeric data.") from err
# count, remove nulls (from the index), and but the bins
result = ii.value_counts(dropna=dropna)
result.name = name
result = result[result.index.notna()]
result.index = result.index.astype("interval")
result = result.sort_index()
# if we are dropna and we have NO values
if dropna and (result._values == 0).all():
result = result.iloc[0:0]
# normalizing is by len of all (regardless of dropna)
normalize_denominator = len(ii)
else:
normalize_denominator = None
if is_extension_array_dtype(values):View on GitHub (pinned to 3b7651241d)