Repository: pandas-dev/pandas
File: pandas/core/algorithms.py (Python)

Code before:
            result.index.names = values.names
            # error: Incompatible types in assignment (expression has type
            # "ndarray[Any, Any] | DatetimeArray | TimedeltaArray | PeriodArray | Any",
            # variable has type "ndarray[tuple[int, ...], dtype[Any]]")
            counts = result._values  # type: ignore[assignment]

        else:
            values = _ensure_arraylike(values, func_name="value_counts")
            keys, counts, _ = value_counts_arraylike(values, dropna)
            if keys.dtype == np.float16:
                keys = keys.astype(np.float32)

            # Starting in 3.0, we no longer perform dtype inference on the
            #  Index object we construct here, xref GH#56161
            idx = Index(keys, dtype=keys.dtype, name=index_name)

            if (
                bins is None
                and not sort
                and isinstance(values, (DatetimeIndex, TimedeltaIndex))
                and values.inferred_freq is not None
                and len(idx) == len(values)
                and idx.equals(values)
            ):
                # freq preservation
                # Rebuild idx with the correct type and inferred frequency
                idx.freq = values.inferred_freq  # type: ignore[attr-defined]

            result = Series(counts, index=idx, name=name, copy=False)

    if sort:
        result = result.sort_values(ascending=ascending)

    if normalize:
        result = result / counts.sum()

    return result


# Called once from SparseArray, otherwise could be private
def value_counts_arraylike(
    values: np.ndarray, dropna: bool, mask: npt.NDArray[np.bool_] | None = None
) -> tuple[ArrayLike, npt.NDArray[np.int64], int]:
    """
    Parameters
    ----------
    values : np.ndarray
    dropna : bool
    mask : np.ndarray[bool] or None, default None

    Returns

Review comment (suggestion):
```suggestion
                # Preserve freq of original index
```

Code after:
            result.index.names = values.names
            # error: Incompatible types in assignment (expression has type
            # "ndarray[Any, Any] | DatetimeArray | TimedeltaArray | PeriodArray | Any",
            # variable has type "ndarray[tuple[int, ...], dtype[Any]]")
            counts = result._values  # type: ignore[assignment]

        else:
            values = _ensure_arraylike(values, func_name="value_counts")
            keys, counts, _ = value_counts_arraylike(values, dropna)
            if keys.dtype == np.float16:
                keys = keys.astype(np.float32)

            # Starting in 3.0, we no longer perform dtype inference on the
            #  Index object we construct here, xref GH#56161
            idx = Index(keys, dtype=keys.dtype, name=index_name)

            if (
                bins is None
                and not sort
                and isinstance(values, (DatetimeIndex, TimedeltaIndex))
                and idx.equals(values)
                and values.inferred_freq is not None
            ):
                # Preserve freq of original index
                idx.freq = values.inferred_freq  # type: ignore[attr-defined]

            result = Series(counts, index=idx, name=name, copy=False)

    if sort:
        result = result.sort_values(ascending=ascending)

    if normalize:
        result = result / counts.sum()

    return result


# Called once from SparseArray, otherwise could be private
def value_counts_arraylike(
    values: np.ndarray, dropna: bool, mask: npt.NDArray[np.bool_] | None = None
) -> tuple[ArrayLike, npt.NDArray[np.int64], int]:
    """
    Parameters
    ----------
    values : np.ndarray
    dropna : bool
    mask : np.ndarray[bool] or None, default None

    Returns
    -------
    uniques : np.ndarray