ronantakizawa/codereview-bench huggingface dataset:
Repository: pandas-dev/pandas
File: pandas/tests/extension/test_arrow.py (Python)

Code before:
    expected = pd.Series([42.0, 42.0, np.nan], dtype="float64")
    tm.assert_series_equal(result, expected)


def test_categorical_from_arrow_dictionary():
    # GH 60563
    df = pd.DataFrame(
        {"A": ["a1", "a2"]}, dtype=ArrowDtype(pa.dictionary(pa.int32(), pa.utf8()))
    )
    result = df.value_counts(dropna=False)
    expected = pd.Series(
        [1, 1],
        index=pd.MultiIndex.from_arrays(
            [pd.Index(["a1", "a2"], dtype=ArrowDtype(pa.string()), name="A")]
        ),
        name="count",
        dtype="int64",
    )
    tm.assert_series_equal(result, expected)


def test_arrow_json_type():
    # GH 60958
    dtype = ArrowDtype(pa.json_(pa.string()))
    result = dtype.type
    assert result == str


Review comment (suggestion):
You'll need to `@pytest.mark.skipif(pa_version_under19p0, reason=...)` as `pa.json_` is new as of Pyarrow 19

Code after:
    result = ser.map(lambda x: 42, na_action="ignore")
    expected = pd.Series([42.0, 42.0, np.nan], dtype="float64")
    tm.assert_series_equal(result, expected)


def test_categorical_from_arrow_dictionary():
    # GH 60563
    df = pd.DataFrame(
        {"A": ["a1", "a2"]}, dtype=ArrowDtype(pa.dictionary(pa.int32(), pa.utf8()))
    )
    result = df.value_counts(dropna=False)
    expected = pd.Series(
        [1, 1],
        index=pd.MultiIndex.from_arrays(
            [pd.Index(["a1", "a2"], dtype=ArrowDtype(pa.string()), name="A")]
        ),
        name="count",
        dtype="int64",
    )
    tm.assert_series_equal(result, expected)


@pytest.mark.skipif(
    pa_version_under19p0, reason="pa.json_ was introduced in pyarrow v19.0"
)
def test_arrow_json_type():
    # GH 60958
    dtype = ArrowDtype(pa.json_(pa.string()))
    result = dtype.type
    assert result == str
Repository: pandas-dev/pandas
File: pandas/tests/indexes/test_base.py (Python)

Code before:

@td.skip_if_no("pyarrow")
def test_is_monotonic_pyarrow_list_type():
    # GH 57333
    import pyarrow as pa

    idx = Index([[1], [2, 3]], dtype=pd.ArrowDtype(pa.list_(pa.int64())))
    assert not idx.is_monotonic_increasing
    assert not idx.is_monotonic_decreasing


@pytest.mark.parametrize(
    "dtype",
    [
        "string[python]",
        pytest.param(
            "string[pyarrow]",
            marks=td.skip_if_no("pyarrow"),
        ),
        pytest.param(
            "str",
            marks=td.skip_if_no("pyarrow"),
        ),
    ],
)
def test_index_equals_different_string_dtype(dtype):
    # GH 61099
    idx_obj = Index(["a", "b", "c"])
    idx_str = Index(["a", "b", "c"], dtype=dtype)

    assert idx_obj.equals(idx_str)
    assert idx_str.equals(idx_obj)


@pytest.mark.parametrize(
    "dtype",
    [
        "string[python]",
        pytest.param(
            "string[pyarrow]",
            marks=td.skip_if_no("pyarrow"),
        ),
        pytest.param(
            "str",
            marks=td.skip_if_no("pyarrow"),
        ),
    ],
)
def test_index_comparison_different_string_dtype(dtype):
    # GH 61099
    idx = Index(["a", "b", "c"])

Review comment (suggestion):
Can you instead use the fixture `string_dtype_no_object` throughout these tests.

Code after:

@td.skip_if_no("pyarrow")
def test_is_monotonic_pyarrow_list_type():
    # GH 57333
    import pyarrow as pa

    idx = Index([[1], [2, 3]], dtype=pd.ArrowDtype(pa.list_(pa.int64())))
    assert not idx.is_monotonic_increasing
    assert not idx.is_monotonic_decreasing


def test_index_equals_different_string_dtype(string_dtype_no_object):
    # GH 61099
    idx_obj = Index(["a", "b", "c"])
    idx_str = Index(["a", "b", "c"], dtype=string_dtype_no_object)

    assert idx_obj.equals(idx_str)
    assert idx_str.equals(idx_obj)


def test_index_comparison_different_string_dtype(string_dtype_no_object):
    # GH 61099
    idx = Index(["a", "b", "c"])
    s_obj = Series([1, 2, 3], index=idx)
    s_str = Series([4, 5, 6], index=idx.astype(string_dtype_no_object))

    expected = Series([True, True, True], index=["a", "b", "c"])
    result = s_obj < s_str
    assert_series_equal(result, expected)

    result = s_str > s_obj
    expected.index = idx.astype(string_dtype_no_object)
    assert_series_equal(result, expected)
Repository: pandas-dev/pandas
File: pandas/core/sample.py (Python)

Code before:
    replace : bool
        Allow or disallow sampling of the same row more than once.
    weights : np.ndarray[np.float64] or None
        If None, equal probability weighting, otherwise weights according
        to the vector normalized
    random_state: np.random.RandomState or np.random.Generator
        State used for the random sampling

    Returns
    -------
    np.ndarray[np.intp]
    """
    if weights is not None:
        weight_sum = weights.sum()
        if weight_sum != 0:
            weights = weights / weight_sum
        else:
            raise ValueError("Invalid weights: weights sum to zero")

    if weights is not None:
        is_max_weight_dominating = size * weights.max() > 1
        if is_max_weight_dominating and not replace:
            raise ValueError(
                "Invalid weights: If `replace`=False, "
                "total unit probabilities have to be less than 1"
            )

    return random_state.choice(obj_len, size=size, replace=replace, p=weights).astype(
        np.intp, copy=False
    )


Review comment (performance):
- Avoid O(n) computation if it is not needed.
- Combine with the `if` block above; no need to check `if weights is not None` twice.
- Suggestion on a more clear error message.

```suggestion
        if not replace and size * weights.max() > 1:
            raise ValueError(
                "Weighted sampling cannot be achieved with replace=False. Either "
                "set replace=True or use smaller weights. See the docstring of sample "
                "for details."
            )
```

Code after:
    replace : bool
        Allow or disallow sampling of the same row more than once.
    weights : np.ndarray[np.float64] or None
        If None, equal probability weighting, otherwise weights according
        to the vector normalized
    random_state: np.random.RandomState or np.random.Generator
        State used for the random sampling

    Returns
    -------
    np.ndarray[np.intp]
    """
    if weights is not None:
        weight_sum = weights.sum()
        if weight_sum != 0:
            weights = weights / weight_sum
        else:
            raise ValueError("Invalid weights: weights sum to zero")

        assert weights is not None  # for mypy
        if not replace and size * weights.max() > 1:
            raise ValueError(
                "Weighted sampling cannot be achieved with replace=False. Either "
                "set replace=True or use smaller weights. See the docstring of "
                "sample for details."
            )

    return random_state.choice(obj_len, size=size, replace=replace, p=weights).astype(
        np.intp, copy=False
    )
Repository: pandas-dev/pandas
File: pandas/compat/pyarrow.py (Python)

Code before:
"""support pyarrow compatibility across versions"""

from __future__ import annotations

from pandas.util.version import Version

try:
    import pyarrow as pa

    _palv = Version(Version(pa.__version__).base_version)
    pa_version_under11p0 = _palv < Version("11.0.0")
    pa_version_under12p1 = _palv < Version("12.0.1")
    pa_version_under13p0 = _palv < Version("13.0.0")
    pa_version_under14p0 = _palv < Version("14.0.0")
    pa_version_under14p1 = _palv < Version("14.0.1")
    pa_version_under15p0 = _palv < Version("15.0.0")
    pa_version_under16p0 = _palv < Version("16.0.0")
    pa_version_under17p0 = _palv < Version("17.0.0")
    pa_version_under18p0 = _palv < Version("18.0.0")
    pa_version_under19p0 = _palv < Version("19.0.0")
    pa_version_under20p0 = _palv < Version("20.0.0")
    HAS_PYARROW = _palv >= Version("12.0.1")
except ImportError:
    pa_version_under11p0 = True
    pa_version_under12p1 = True
    pa_version_under13p0 = True
    pa_version_under14p0 = True
    pa_version_under14p1 = True
    pa_version_under15p0 = True
    pa_version_under16p0 = True
    pa_version_under17p0 = True
    pa_version_under18p0 = True
    pa_version_under19p0 = True
    pa_version_under20p0 = True
    HAS_PYARROW = False


Review comment (suggestion):
I checked the current usages of `HAS_PYARROW` and essentially everywhere we mean it to be a supported version of pyarrow (didnt check the tests, but those we run only with supported versions anyway).

By changing the definition here, we can use `HAS_PYARROW` in other places to protect imports (the ones that were now using `if not pa_version_under10p1`), and then we don't have to update those everytime updating the minimum version.

Code after:
"""support pyarrow compatibility across versions"""

from __future__ import annotations

from pandas.util.version import Version

try:
    import pyarrow as pa

    _palv = Version(Version(pa.__version__).base_version)
    pa_version_under12p1 = _palv < Version("12.0.1")
    pa_version_under13p0 = _palv < Version("13.0.0")
    pa_version_under14p0 = _palv < Version("14.0.0")
    pa_version_under14p1 = _palv < Version("14.0.1")
    pa_version_under15p0 = _palv < Version("15.0.0")
    pa_version_under16p0 = _palv < Version("16.0.0")
    pa_version_under17p0 = _palv < Version("17.0.0")
    pa_version_under18p0 = _palv < Version("18.0.0")
    pa_version_under19p0 = _palv < Version("19.0.0")
    pa_version_under20p0 = _palv < Version("20.0.0")
    HAS_PYARROW = _palv >= Version("12.0.1")
except ImportError:
    pa_version_under12p1 = True
    pa_version_under13p0 = True
    pa_version_under14p0 = True
    pa_version_under14p1 = True
    pa_version_under15p0 = True
    pa_version_under16p0 = True
    pa_version_under17p0 = True
    pa_version_under18p0 = True
    pa_version_under19p0 = True
    pa_version_under20p0 = True
    HAS_PYARROW = False
Repository: pandas-dev/pandas
File: pandas/core/generic.py (Python)

Code before:

        Returns
        -------
        DataFrame, Series, or scalar
            The projection after squeezing `axis` or all the axes.

        See Also
        --------
        Series.iloc : Integer-location based indexing for selecting scalars.
        DataFrame.iloc : Integer-location based indexing for selecting Series.
        Series.to_frame : Inverse of DataFrame.squeeze for a
            single-column DataFrame.

        Examples
        --------
        >>> primes = pd.Series([2, 3, 5, 7])

        Slicing might produce a Series with a single value:

        >>> even_primes = primes[primes % 2 == 0]
        >>> even_primes
        0    2
        dtype: int64

        >>> even_primes.squeeze()
        2

        Squeezing objects with more than one value in every axis does nothing:

        >>> odd_primes = primes[primes % 2 == 1]
        >>> odd_primes
        1    3
        2    5
        3    7
        dtype: int64

        >>> odd_primes.squeeze()
        1    3
        2    5
        3    7
        dtype: int64

        Squeezing is even more effective when used with DataFrames.

        >>> df = pd.DataFrame([[1, 2], [3, 4]], columns=["a", "b"])
        >>> df
           a  b
        0  1  2
        1  3  4

        Slicing a single column will produce a DataFrame with the columns

Review comment (suggestion):
With which version of numpy are you running the doctests locally? 
I personally don't particularly like the `np.int64(2)` repr for in the docstrings, but I see that was recently changed in https://github.com/pandas-dev/pandas/pull/60987 to follow the latest numpy

Code after:

        Returns
        -------
        DataFrame, Series, or scalar
            The projection after squeezing `axis` or all the axes.

        See Also
        --------
        Series.iloc : Integer-location based indexing for selecting scalars.
        DataFrame.iloc : Integer-location based indexing for selecting Series.
        Series.to_frame : Inverse of DataFrame.squeeze for a
            single-column DataFrame.

        Examples
        --------
        >>> primes = pd.Series([2, 3, 5, 7])

        Slicing might produce a Series with a single value:

        >>> even_primes = primes[primes % 2 == 0]
        >>> even_primes
        0    2
        dtype: int64

        >>> even_primes.squeeze()
        np.int64(2)

        Squeezing objects with more than one value in every axis does nothing:

        >>> odd_primes = primes[primes % 2 == 1]
        >>> odd_primes
        1    3
        2    5
        3    7
        dtype: int64

        >>> odd_primes.squeeze()
        1    3
        2    5
        3    7
        dtype: int64

        Squeezing is even more effective when used with DataFrames.

        >>> df = pd.DataFrame([[1, 2], [3, 4]], columns=["a", "b"])
        >>> df
           a  b
        0  1  2
        1  3  4

        Slicing a single column will produce a DataFrame with the columns
Repository: pandas-dev/pandas
File: pandas/util/_print_versions.py (Python)

Code before:
    commit           : 37ea63d540fd27274cad6585082c91b1283f963d
    python           : 3.10.6.final.0
    python-bits      : 64
    OS               : Linux
    OS-release       : 5.10.102.1-microsoft-standard-WSL2
    Version          : #1 SMP Wed Mar 2 00:30:59 UTC 2022
    machine          : x86_64
    processor        : x86_64
    byteorder        : little
    LC_ALL           : None
    LANG             : en_GB.UTF-8
    LOCALE           : en_GB.UTF-8
    pandas           : 2.0.1
    numpy            : 1.24.3
    ...
    """
    sys_info = _get_sys_info()
    deps = _get_dependency_info()

    if as_json:
        j = {"system": sys_info, "dependencies": deps}

        if as_json is True:
            sys.stdout.writelines(json.dumps(j, indent=2))
        else:
            assert isinstance(as_json, str)  # needed for mypy
            with codecs.open(as_json, "wb", encoding="utf8") as f:
                json.dump(j, f, indent=2)

    else:
        assert isinstance(sys_info["LOCALE"], dict)  # needed for mypy
        language_code = sys_info["LOCALE"]["language-code"]
        encoding = sys_info["LOCALE"]["encoding"]
        sys_info["LOCALE"] = f"{language_code}.{encoding}"

        maxlen = max(len(x) for x in deps)
        print("\nINSTALLED VERSIONS")
        print("------------------")
        for k, v in sys_info.items():
            print(f"{k:<{maxlen}}: {v}")
        print("")
        for k, v in deps.items():
            print(f"{k:<{maxlen}}: {v}")


Review comment (bug):
I changed it from "wb" to "w" because I think the "b" here is a bug (bytes *and* utf-8???)

Code after:
    python           : 3.10.6.final.0
    python-bits      : 64
    OS               : Linux
    OS-release       : 5.10.102.1-microsoft-standard-WSL2
    Version          : #1 SMP Wed Mar 2 00:30:59 UTC 2022
    machine          : x86_64
    processor        : x86_64
    byteorder        : little
    LC_ALL           : None
    LANG             : en_GB.UTF-8
    LOCALE           : en_GB.UTF-8
    pandas           : 2.0.1
    numpy            : 1.24.3
    ...
    """
    sys_info = _get_sys_info()
    deps = _get_dependency_info()

    if as_json:
        j = {"system": sys_info, "dependencies": deps}

        if as_json is True:
            sys.stdout.writelines(json.dumps(j, indent=2))
        else:
            assert isinstance(as_json, str)  # needed for mypy
            with open(as_json, "w", encoding="utf-8") as f:
                json.dump(j, f, indent=2)

    else:
        assert isinstance(sys_info["LOCALE"], dict)  # needed for mypy
        language_code = sys_info["LOCALE"]["language-code"]
        encoding = sys_info["LOCALE"]["encoding"]
        sys_info["LOCALE"] = f"{language_code}.{encoding}"

        maxlen = max(len(x) for x in deps)
        print("\nINSTALLED VERSIONS")
        print("------------------")
        for k, v in sys_info.items():
            print(f"{k:<{maxlen}}: {v}")
        print("")
        for k, v in deps.items():
            print(f"{k:<{maxlen}}: {v}")
Repository: pandas-dev/pandas
File: pandas/core/col.py (Python)

Code before:
            # Create a readable representation for namespace method calls
            args_repr = ", ".join(
                repr(arg._repr_str if isinstance(arg, Expr) else arg) for arg in args
            )
            kwargs_repr = ", ".join(
                f"{k}={v._repr_str if isinstance(v, Expr) else v!r}"
                for k, v in kwargs.items()
            )

            all_args = []
            if args_repr:
                all_args.append(args_repr)
            if kwargs_repr:
                all_args.append(kwargs_repr)

            args_str = ", ".join(all_args)
            repr_str = f"{self._func._repr_str}.{self._namespace}.{attr}({args_str})"

            return Expr(lambda df: func(df, *args, **kwargs), repr_str)

        return wrapper


def col(col_name: Hashable) -> Expr:
    """
    Generate deferred objected representing a dataframe's column.

    Any place which accepts ``lambda df: df[col_name]``, such as
    :meth:`DataFrame.assign` or :meth:`DataFrame.loc`, can also accept
    ``pd.col(col_name)``.

    Arguments
    ---------
    col_name : Hashable
        Column name.

    Returns
    -------
    Expr

    Examples
    --------

    You can use `col` in `assign`.

    >>> df = pd.DataFrame({"name": ["beluga", "narwhal"], "speed": [100, 110]})
    >>> df.assign(name_titlecase=pd.col("name").str.title())
          name  speed name_titlecase
    0   beluga    100         Beluga
    1  narwhal    110        Narwhal


Review comment (suggestion):
```suggestion
    Generate deferred object representing a column of a `DataFrame`
```

Code after:
def col(col_name: Hashable) -> Expression:
    """
    Generate deferred object representing a column of a DataFrame.

    Any place which accepts ``lambda df: df[col_name]``, such as
    :meth:`DataFrame.assign` or :meth:`DataFrame.loc`, can also accept
    ``pd.col(col_name)``.

    Parameters
    ----------
    col_name : Hashable
        Column name.

    Returns
    -------
    `pandas.api.typing.Expression`
        A deferred object representing a column of a DataFrame.

    See Also
    --------
    DataFrame.query : Query columns of a dataframe using string expressions.

    Examples
    --------

    You can use `col` in `assign`.

    >>> df = pd.DataFrame({"name": ["beluga", "narwhal"], "speed": [100, 110]})
    >>> df.assign(name_titlecase=pd.col("name").str.title())
          name  speed name_titlecase
    0   beluga    100         Beluga
    1  narwhal    110        Narwhal

    You can also use it for filtering.

    >>> df.loc[pd.col("speed") > 105]
          name  speed
    1  narwhal    110
    """
    if not isinstance(col_name, Hashable):
        msg = f"Expected Hashable, got: {type(col_name)}"
        raise TypeError(msg)

    def func(df: DataFrame) -> Series:
        if col_name not in df.columns:
            columns_str = str(df.columns.tolist())
            max_len = 90
            if len(columns_str) > max_len:
                columns_str = columns_str[:max_len] + "...]"

            msg = (
Repository: pandas-dev/pandas
File: pandas/core/col.py (Python)

Code before:
                all_args.append(kwargs_repr)

            args_str = ", ".join(all_args)
            repr_str = f"{self._func._repr_str}.{self._namespace}.{attr}({args_str})"

            return Expression(lambda df: func(df, *args, **kwargs), repr_str)

        return wrapper


def col(col_name: Hashable) -> Expression:
    """
    Generate deferred object representing a column of a `DataFrame`.

    Any place which accepts ``lambda df: df[col_name]``, such as
    :meth:`DataFrame.assign` or :meth:`DataFrame.loc`, can also accept
    ``pd.col(col_name)``.

    Arguments
    ---------
    col_name : Hashable
        Column name.

    Returns
    -------
    Expr

    Examples
    --------

    You can use `col` in `assign`.

    >>> df = pd.DataFrame({"name": ["beluga", "narwhal"], "speed": [100, 110]})
    >>> df.assign(name_titlecase=pd.col("name").str.title())
          name  speed name_titlecase
    0   beluga    100         Beluga
    1  narwhal    110        Narwhal

    You can also use it for filtering.

    >>> df.loc[pd.col("speed") > 105]
          name  speed
    1  narwhal    110
    """
    if not isinstance(col_name, Hashable):
        msg = f"Expected Hashable, got: {type(col_name)}"
        raise TypeError(msg)

    def func(df: DataFrame) -> Series:
        if col_name not in df.columns:
            msg = (

Review comment (suggestion):
```suggestion
    `pandas.api.typing.Expression`
```

Code after:
            repr_str = f"{self._func._repr_str}.{self._namespace}.{attr}({args_str})"
            return Expression(lambda df: func(df, *args, **kwargs), repr_str)

        return wrapper


def col(col_name: Hashable) -> Expression:
    """
    Generate deferred object representing a column of a DataFrame.

    Any place which accepts ``lambda df: df[col_name]``, such as
    :meth:`DataFrame.assign` or :meth:`DataFrame.loc`, can also accept
    ``pd.col(col_name)``.

    Parameters
    ----------
    col_name : Hashable
        Column name.

    Returns
    -------
    `pandas.api.typing.Expression`
        A deferred object representing a column of a DataFrame.

    See Also
    --------
    DataFrame.query : Query columns of a dataframe using string expressions.

    Examples
    --------

    You can use `col` in `assign`.

    >>> df = pd.DataFrame({"name": ["beluga", "narwhal"], "speed": [100, 110]})
    >>> df.assign(name_titlecase=pd.col("name").str.title())
          name  speed name_titlecase
    0   beluga    100         Beluga
    1  narwhal    110        Narwhal

    You can also use it for filtering.

    >>> df.loc[pd.col("speed") > 105]
          name  speed
    1  narwhal    110
    """
    if not isinstance(col_name, Hashable):
        msg = f"Expected Hashable, got: {type(col_name)}"
        raise TypeError(msg)

    def func(df: DataFrame) -> Series:
        if col_name not in df.columns: