internlm/SWE-Fixer-Train-110K huggingface dataset:
Repository: pandas-dev/pandas

Issue:
algos.take calling validate_indices incorrectly?
https://github.com/pandas-dev/pandas/blob/master/pandas/core/algorithms.py#L1528

In core.algorithms.take:

```
    if allow_fill:
        # Pandas style, -1 means NA
        validate_indices(indices, len(arr))
        result = take_1d(arr, indices, axis=axis, allow_fill=True,
fill_value=fill_value)
```

It looks to me like the `validate_indices` call should be `validate_indices(indices, arr.shape[axis])`.

Found while attempting to simplify #26914.


Discussion:
yes this looks to be incorrect

Resolving patch:
diff --git a/pandas/core/algorithms.py b/pandas/core/algorithms.py
--- a/pandas/core/algorithms.py
+++ b/pandas/core/algorithms.py
@@ -1526,7 +1526,7 @@ def take(arr, indices, axis=0, allow_fill=False, fill_value=None):
 
     if allow_fill:
         # Pandas style, -1 means NA
-        validate_indices(indices, len(arr))
+        validate_indices(indices, arr.shape[axis])
         result = take_1d(arr, indices, axis=axis, allow_fill=True,
                          fill_value=fill_value)
     else:
diff --git a/pandas/core/arrays/sparse.py b/pandas/core/arrays/sparse.py
--- a/pandas/core/arrays/sparse.py
+++ b/pandas/core/arrays/sparse.py
@@ -1868,15 +1868,6 @@ def _maybe_to_dense(obj):
     return obj
 
 
-def _maybe_to_sparse(array):
-    """
-    array must be SparseSeries or SparseArray
-    """
-    if isinstance(array, ABCSparseSeries):
-        array = array.array.copy()
-    return array
-
-
 def make_sparse(arr, kind='block', fill_value=None, dtype=None, copy=False):
     """
     Convert ndarray to sparse format


Test patch:
diff --git a/pandas/tests/test_take.py b/pandas/tests/test_take.py
--- a/pandas/tests/test_take.py
+++ b/pandas/tests/test_take.py
@@ -420,6 +420,11 @@ def test_take_axis_1(self):
         expected = np.array([[0, 0], [3, 0], [6, 0], [9, 0]])
         tm.assert_numpy_array_equal(result, expected)
 
+        # GH#26976 make sure we validate along the correct axis
+        with pytest.raises(IndexError, match="indices are out-of-bounds"):
+            algos.take(arr, [0, 3], axis=1, allow_fill=True,
+                       fill_value=0)
+
 
 class TestExtensionTake:
     # The take method found in pd.api.extensions
Repository: pandas-dev/pandas

Issue:
Behavior change in Index.equals from 0.18.0 to 0.19.0 -- intentional?
Traditionally, we have:

``` python
In [3]: pandas.__version__
Out[3]: '0.18.0'

In [4]: pandas.Index([1, 2]).equals([1, 2])
Out[4]: True
```

But this changed

``` python
In [4]: pandas.__version__
Out[4]: '0.19.0'

In [5]: pandas.Index([1, 2]).equals([1, 2])
Out[5]: False
```

Looks like it might not be intentional so FYI.

(Noticed because it broke a few tests in the patsy test suite.)



Discussion:
Well, we had some discussion about this, see https://github.com/pandas-dev/pandas/pull/13986#r74693208 (I thought we had a longer discussion somewhere else, but can't find it directly), but I think I lost the discussion for allowing this. 
Basically, to be equal to an index, you now have to be an index yourself (so a list can no longer be equal). But I see we didn't really explain this in the whatsnew docs.

I can see the argument for the new behavior, but it was a backwards incompatible change with no deprecation, so wasn't sure what was going on.

I've already worked around it for patsy.


Resolving patch:
diff --git a/pandas/core/indexes/base.py b/pandas/core/indexes/base.py
--- a/pandas/core/indexes/base.py
+++ b/pandas/core/indexes/base.py
@@ -4170,7 +4170,8 @@ def equals(self, other):
         Returns
         -------
         bool
-            If two Index objects have equal elements True, otherwise False.
+            True if "other" is an Index and it has the same elements as calling
+            index; False otherwise.
         """
         if self.is_(other):
             return True


Test patch:
Repository: pandas-dev/pandas

Issue:
DOC: Index.get_loc Cannot Accept List-like Tolerance
The docs for `Index.get_loc` suggest that the tolerance parameter may accept both a scalar and list-like argument. However, I don't think this is actually possible:

```python
# Can only pass scalar label to unique Index, so tolerance cannot be list-like
>>> pd.Index([0, 1, 2]).get_loc(1)
1
>>> pd.Index([0, 1, 2]).get_loc([1, 1])
TypeError: '[1, 1]' is an invalid key

# Inexact matches do not work against non-unique index
>>> pd.Index([1, 1, 2]).get_loc(1.1, method='nearest')
pandas.core.indexes.base.InvalidIndexError: Reindexing only valid with uniquely valued Index objects
```

In short I don't think this method can ever return a list using inexact matches. IIUC the documented list-like `tolerance` argument is therefore invalid. 

I don't see any tests for this behavior and my assumption is it was documented as part of this methods overlap with `get_indexer`, but the documentation for `get_loc` should be updated to reflect what can actually be accepted


Discussion:
is this just a doc issue? the above looks correct 
If the above is all correct then yes it is a doc issue.  Below is taken directly from the API docs:

"Tolerance may be a scalar value, which applies the same tolerance to all values, or list-like, which applies variable tolerance per element..."


yeah above is correct 
not sure if it’s noted but get_loc requires a unique index


I think that limitation only applies when doing anything but an exact match.

```python
>>> index = pd.Index([1, 1, 1])
>>> index.get_loc(1)
slice(0, 3, None)
>>> index.get_loc(1, method='pad')
pandas.core.indexes.base.InvalidIndexError: Reindexing only valid with uniquely valued Index objects
```

The docs even provide an example of this. Regardless good opportunity for cleanup here

Resolving patch:
diff --git a/pandas/core/indexes/base.py b/pandas/core/indexes/base.py
--- a/pandas/core/indexes/base.py
+++ b/pandas/core/indexes/base.py
@@ -2724,17 +2724,11 @@ def _convert_can_do_setop(self, other):
             * backfill / bfill: use NEXT index value if no exact match
             * nearest: use the NEAREST index value if no exact match. Tied
               distances are broken by preferring the larger index value.
-        tolerance : optional
+        tolerance : int or float, optional
             Maximum distance from index value for inexact matches. The value of
             the index at the matching location most satisfy the equation
             ``abs(index[loc] - key) <= tolerance``.
 
-            Tolerance may be a scalar
-            value, which applies the same tolerance to all values, or
-            list-like, which applies variable tolerance per element. List-like
-            includes list, tuple, array, Series, and must be the same size as
-            the index and its dtype must exactly match the index's type.
-
             .. versionadded:: 0.21.0 (list-like tolerance)
 
         Returns


Test patch:
Repository: pandas-dev/pandas

Issue:
"on" argument of DataFrame.rolling only works for datetime columns
the `on=` argument of `DataFrame.rolling` only works for datetime columns.

```
df = pd.DataFrame([
    [18, 0],
    [2, 0],
    [1, 0],
    [9, 1],
    [8, 1],
], columns=['value', 'roll'])
```

```
df.roll = pd.to_datetime(df.roll, unit='s')
df.rolling('1s', on='roll').value.max()
```

returns:

```
0    18.0
1    18.0
2    18.0
3     9.0
4     9.0
Name: value, dtype: float64
```
as expected.

But 

```df.rolling(1, on='roll').value.max()```

returns:

```
0    18.0
1     2.0
2     1.0
3     9.0
4     8.0
Name: value, dtype: float64
```

If this is intentional behavior, I'd be happy to change the docs to note this (the docs currently imply that `on=` can be used for any column).






Discussion:
cc @jreback @jorisvandenbossche 

Resolving patch:
diff --git a/pandas/core/window.py b/pandas/core/window.py
--- a/pandas/core/window.py
+++ b/pandas/core/window.py
@@ -513,8 +513,10 @@ class Window(_Window):
         Provide a window type. If ``None``, all points are evenly weighted.
         See the notes below for further information.
     on : str, optional
-        For a DataFrame, column on which to calculate
-        the rolling window, rather than the index.
+        For a DataFrame, a datetime-like column on which to calculate the rolling
+        window, rather than the DataFrame's index. Provided integer column is
+        ignored and excluded from result since an integer index is not used to
+        calculate the rolling window.
     axis : int or str, default 0
     closed : str, default None
         Make the interval closed on the 'right', 'left', 'both' or


Test patch:
Repository: pandas-dev/pandas

Issue:
ENH: maybe_convert_objects seen NaT speed-up
I believe after `seen.object_ = 1` here:
https://github.com/pandas-dev/pandas/blob/c64c9cb44222a42f7b02d4d6007919cd0645f1be/pandas/_libs/lib.pyx#L1956-L1958
should go `break` as well.

Test:
```python
size = 10**7
arr = list(range(size))
arr[0] = pd.NaT
arr = np.array(arr)
```
```python
%timeit lib.maybe_convert_objects(arr, convert_datetime=0, convert_timedelta=0)
```
As now output is:
```python
1.84 s ± 14.3 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
```
With `break`:
```python
57.1 µs ± 887 ns per loop (mean ± std. dev. of 7 runs, 10000 loops each)
```
And both cases produce same array:
```python
array([NaT, 1, 2, ..., 9999997, 9999998, 9999999], dtype=object)
```


Discussion:

Resolving patch:
diff --git a/asv_bench/benchmarks/algorithms.py b/asv_bench/benchmarks/algorithms.py
--- a/asv_bench/benchmarks/algorithms.py
+++ b/asv_bench/benchmarks/algorithms.py
@@ -2,6 +2,8 @@
 
 import numpy as np
 
+from pandas._libs import lib
+
 import pandas as pd
 from pandas.util import testing as tm
 
@@ -13,6 +15,19 @@
         pass
 
 
+class MaybeConvertObjects:
+    def setup(self):
+        N = 10 ** 5
+
+        data = list(range(N))
+        data[0] = pd.NaT
+        data = np.array(data)
+        self.data = data
+
+    def time_maybe_convert_objects(self):
+        lib.maybe_convert_objects(self.data)
+
+
 class Factorize:
 
     params = [[True, False], ["int", "uint", "float", "string"]]


Test patch:
Repository: pandas-dev/pandas

Issue:
BUG: DatetimeArray/Series incorrectly accepts timedelta64('NaT') for __setitem__
```
dti = pd.date_range('2016-01-01', periods=3)
nat = np.timedelta64('NaT')

dta = dti._data.copy()
dta[0] = nat  # <-- should raise TypeError, doesn't

ser = pd.Series(dti.copy())
ser[1] = nat  # <-- should raise TypeError, doesn't

df = pd.DataFrame(dti.copy())
df.loc[2, 0] = nat  # <-- should raise TypeError, doesn't
```

I haven't checked, but I expect the same thing happens in reverse for Timedelta, possible Period dtypes.


Discussion:

Resolving patch:
diff --git a/pandas/core/internals/blocks.py b/pandas/core/internals/blocks.py
--- a/pandas/core/internals/blocks.py
+++ b/pandas/core/internals/blocks.py
@@ -2589,8 +2589,9 @@ def setitem(self, indexer, value):
         try:
             return super().setitem(indexer, value)
         except (ValueError, TypeError):
+            obj_vals = self.values.astype(object)
             newb = make_block(
-                self.values.astype(object), placement=self.mgr_locs, klass=ObjectBlock
+                obj_vals, placement=self.mgr_locs, klass=ObjectBlock, ndim=self.ndim
             )
             return newb.setitem(indexer, value)
 


Test patch:
diff --git a/pandas/tests/series/indexing/test_indexing.py b/pandas/tests/series/indexing/test_indexing.py
--- a/pandas/tests/series/indexing/test_indexing.py
+++ b/pandas/tests/series/indexing/test_indexing.py
@@ -654,6 +654,38 @@ def test_timedelta_assignment():
     tm.assert_series_equal(s, expected)
 
 
+@pytest.mark.parametrize(
+    "nat_val,should_cast",
+    [
+        (pd.NaT, True),
+        (np.timedelta64("NaT", "ns"), False),
+        (np.datetime64("NaT", "ns"), True),
+    ],
+)
+@pytest.mark.parametrize("tz", [None, "UTC"])
+def test_dt64_series_assign_nat(nat_val, should_cast, tz):
+    # some nat-like values should be cast to datetime64 when inserting
+    #  into a datetime64 series.  Others should coerce to object
+    #  and retain their dtypes.
+    dti = pd.date_range("2016-01-01", periods=3, tz=tz)
+    base = pd.Series(dti)
+    expected = pd.Series([pd.NaT] + list(dti[1:]), dtype=dti.dtype)
+    if not should_cast:
+        expected = expected.astype(object)
+
+    ser = base.copy(deep=True)
+    ser[0] = nat_val
+    tm.assert_series_equal(ser, expected)
+
+    ser = base.copy(deep=True)
+    ser.loc[0] = nat_val
+    tm.assert_series_equal(ser, expected)
+
+    ser = base.copy(deep=True)
+    ser.iloc[0] = nat_val
+    tm.assert_series_equal(ser, expected)
+
+
 @pytest.mark.parametrize(
     "nat_val,should_cast",
     [
Repository: pandas-dev/pandas

Issue:
Write fast OHLC aggregator
To work with GroupBy



Discussion:
speed of current OHLC function can be improved:

```
def translate_grouping(how):
    if set(how) == set('ohlc'):
        return {'open'  : lambda arr: arr[0],
                'low'   : lambda arr: arr.min(),
                'high'  : lambda arr: arr.max(),
                'close' : lambda arr: arr[-1]}

    if how in 'last':
        def picker(arr):
            return arr[-1] if arr is not None and len(arr) else np.nan
        return picker

    raise ValueError("Unrecognized method: %s" % how)
```


Resolving patch:
diff --git a/pandas/core/groupby/ops.py b/pandas/core/groupby/ops.py
--- a/pandas/core/groupby/ops.py
+++ b/pandas/core/groupby/ops.py
@@ -20,7 +20,6 @@
     ensure_float64,
     ensure_int64,
     ensure_int_or_float,
-    ensure_object,
     ensure_platform_int,
     is_bool_dtype,
     is_categorical_dtype,
@@ -567,15 +566,8 @@ def _cython_operation(self, kind, values, how, axis, min_count=-1, **kwargs):
                 result[mask] = np.nan
 
         if kind == "aggregate" and self._filter_empty_groups and not counts.all():
-            if result.ndim == 2:
-                try:
-                    result = lib.row_bool_subset(result, (counts > 0).view(np.uint8))
-                except ValueError:
-                    result = lib.row_bool_subset_object(
-                        ensure_object(result), (counts > 0).view(np.uint8)
-                    )
-            else:
-                result = result[counts > 0]
+            assert result.ndim != 2
+            result = result[counts > 0]
 
         if vdim == 1 and arity == 1:
             result = result[:, 0]


Test patch:
Repository: pandas-dev/pandas

Issue:
CLN: Can we remove libalgos.arrmap_*?
Discussed in #27236, after that there will be only one non-test usage of libalgos.arrmap_* and it looks like it may be feasible to just use np.vectorize.  Check if this is correct and if there is a perf impact.


Discussion:

Resolving patch:
diff --git a/pandas/core/algorithms.py b/pandas/core/algorithms.py
--- a/pandas/core/algorithms.py
+++ b/pandas/core/algorithms.py
@@ -1100,7 +1100,9 @@ def _get_score(at):
         return _get_score(q)
     else:
         q = np.asarray(q, np.float64)
-        return algos.arrmap_float64(q, _get_score)
+        result = [_get_score(x) for x in q]
+        result = np.array(result, dtype=np.float64)
+        return result
 
 
 # --------------- #


Test patch:
diff --git a/pandas/tests/test_algos.py b/pandas/tests/test_algos.py
--- a/pandas/tests/test_algos.py
+++ b/pandas/tests/test_algos.py
@@ -1685,12 +1685,6 @@ def test_pad_backfill_object_segfault():
     tm.assert_numpy_array_equal(result, expected)
 
 
-def test_arrmap():
-    values = np.array(["foo", "foo", "bar", "bar", "baz", "qux"], dtype="O")
-    result = libalgos.arrmap_object(values, lambda x: x in ["foo", "bar"])
-    assert result.dtype == np.bool_
-
-
 class TestTseriesUtil:
     def test_combineFunc(self):
         pass
Repository: pandas-dev/pandas

Issue:
BUG: dir(IntervalIndex()) raises
```python

In [8]: ix=pd.IntervalIndex.from_breaks([0,1,2])
   ...: dir(ix)
...
ValueError: cannot infer type for <class 'NoneType'>

```



Discussion:
Thanks for the report @pilkibun! I can confirm this behavior.  Interestingly, `dir(pd.IntervalIndex)` is fine, it's just a constructed `IntervalIndex` that fails.
Looks like in it is calling `ix.str` and taht calls `lib.infer_dtype` which raises because its not looking at an ndarray
I'm new to the project, but from a cursory glance of the documentation `pd.IntervalIndex.from_breaks` only accepts array-likes, and `range(3)` is not an array-like (based on `pd.core.dtypes.inference.is_array_like`.

So, isn't `range(3)` technically an incorrect input?
@vishwakftw the docs for IntervalIndex.from_breaks should maybe be updated to require "list-like" rather than "array-like". I haven't looked closely.

That said, I think that's separate from the issue @pilkibun reported.

Resolving patch:
diff --git a/pandas/core/strings.py b/pandas/core/strings.py
--- a/pandas/core/strings.py
+++ b/pandas/core/strings.py
@@ -1953,8 +1953,11 @@ def _validate(data):
         values = getattr(data, "values", data)  # Series / Index
         values = getattr(values, "categories", values)  # categorical / normal
 
-        # missing values obfuscate type inference -> skip
-        inferred_dtype = lib.infer_dtype(values, skipna=True)
+        try:
+            inferred_dtype = lib.infer_dtype(values, skipna=True)
+        except ValueError:
+            # GH#27571 mostly occurs with ExtensionArray
+            inferred_dtype = None
 
         if inferred_dtype not in allowed_types:
             raise AttributeError("Can only use .str accessor with string values!")


Test patch:
diff --git a/pandas/tests/dtypes/test_inference.py b/pandas/tests/dtypes/test_inference.py
--- a/pandas/tests/dtypes/test_inference.py
+++ b/pandas/tests/dtypes/test_inference.py
@@ -1153,6 +1153,17 @@ def test_categorical(self):
         result = lib.infer_dtype(Series(arr), skipna=True)
         assert result == "categorical"
 
+    def test_interval(self):
+        idx = pd.IntervalIndex.from_breaks(range(5), closed="both")
+        inferred = lib.infer_dtype(idx, skipna=False)
+        assert inferred == "interval"
+
+        inferred = lib.infer_dtype(idx._data, skipna=False)
+        assert inferred == "interval"
+
+        inferred = lib.infer_dtype(pd.Series(idx), skipna=False)
+        assert inferred == "interval"
+
 
 class TestNumberScalar:
     def test_is_number(self):
diff --git a/pandas/tests/indexes/interval/test_interval.py b/pandas/tests/indexes/interval/test_interval.py
--- a/pandas/tests/indexes/interval/test_interval.py
+++ b/pandas/tests/indexes/interval/test_interval.py
@@ -1095,3 +1095,10 @@ def test_is_all_dates(self):
         )
         year_2017_index = pd.IntervalIndex([year_2017])
         assert not year_2017_index.is_all_dates
+
+
+def test_dir():
+    # GH#27571 dir(interval_index) should not raise
+    index = IntervalIndex.from_arrays([0, 1], [1, 2])
+    result = dir(index)
+    assert "str" not in result
Repository: pandas-dev/pandas

Issue:
PERF: Avoid materializing entire IntervalIndex when using cut
When using `cut` with an `IntervalIndex` for `bins` the result of the `cut` is first materialized as an `IntervalIndex` and then converted to a `Categorical`:

https://github.com/pandas-dev/pandas/blob/143bc34aa8f068b18e7137df7ca91b9929cc1389/pandas/core/reshape/tile.py#L373-L378

It seems like it'd be more performant from a computational and memory standpoint to bypass the intermediate construction of an `IntervalIndex` via `take_nd` and instead directly construct the `Categorical` via `Categorical.from_codes`.

Some ad hoc measurements on `master`:
```python
In [3]: ii = pd.interval_range(0, 20)

In [4]: values = np.linspace(0, 20, 100).repeat(10**4)

In [5]: %timeit pd.cut(values, ii)
7.69 s ± 43.5 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

In [6]: %memit pd.cut(values, ii)
peak memory: 278.39 MiB, increment: 130.76 MiB
```
And the same measurements with the `Categorical.from_codes` fix:
```python
In [3]: ii = pd.interval_range(0, 20)

In [4]: values = np.linspace(0, 20, 100).repeat(10**4)

In [5]: %timeit pd.cut(values, ii)
1.02 s ± 18.9 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

In [6]: %memit pd.cut(values, ii)
peak memory: 145.81 MiB, increment: 15.98 MiB
```


Discussion:

Resolving patch:
diff --git a/asv_bench/benchmarks/reshape.py b/asv_bench/benchmarks/reshape.py
--- a/asv_bench/benchmarks/reshape.py
+++ b/asv_bench/benchmarks/reshape.py
@@ -214,6 +214,7 @@ def setup(self, bins):
         self.datetime_series = pd.Series(
             np.random.randint(N, size=N), dtype="datetime64[ns]"
         )
+        self.interval_bins = pd.IntervalIndex.from_breaks(np.linspace(0, N, bins))
 
     def time_cut_int(self, bins):
         pd.cut(self.int_series, bins)
@@ -239,6 +240,14 @@ def time_qcut_timedelta(self, bins):
     def time_qcut_datetime(self, bins):
         pd.qcut(self.datetime_series, bins)
 
+    def time_cut_interval(self, bins):
+        # GH 27668
+        pd.cut(self.int_series, self.interval_bins)
+
+    def peakmem_cut_interval(self, bins):
+        # GH 27668
+        pd.cut(self.int_series, self.interval_bins)
+
 
 class Explode:
     param_names = ["n_rows", "max_list_length"]
diff --git a/pandas/core/reshape/tile.py b/pandas/core/reshape/tile.py
--- a/pandas/core/reshape/tile.py
+++ b/pandas/core/reshape/tile.py
@@ -373,8 +373,7 @@ def _bins_to_cuts(
     if isinstance(bins, IntervalIndex):
         # we have a fast-path here
         ids = bins.get_indexer(x)
-        result = algos.take_nd(bins, ids)
-        result = Categorical(result, categories=bins, ordered=True)
+        result = Categorical.from_codes(ids, categories=bins, ordered=True)
         return result, bins
 
     unique_bins = algos.unique(bins)


Test patch:
Repository: pandas-dev/pandas

Issue:
Windowing fails on read-only arrays
#### Code Sample, a copy-pastable example if possible

```python
>>> arr = np.array([1, 3, np.nan, 3, 5])
>>> arr.setflags(write=False)
>>> pd.Series(arr).rolling(2).mean().values
---------------------------------------------------------------------------
ValueError: assignment destination is read-only
```

#### Expected Output
```py
>>> pd.Series(arr).rolling(2).mean().values
array([nan,  2., nan, nan,  4.])
```
#### Problem description

https://github.com/pandas-dev/pandas/pull/27391#discussion_r309941141 missed a copy call before writing into array, which is user's data and which may be read-only.

#### Output of ``pd.show_versions()``

pandas 0.25.0



Discussion:

Resolving patch:
diff --git a/pandas/core/window.py b/pandas/core/window.py
--- a/pandas/core/window.py
+++ b/pandas/core/window.py
@@ -246,8 +246,10 @@ def _prep_values(self, values: Optional[np.ndarray] = None) -> np.ndarray:
             except (ValueError, TypeError):
                 raise TypeError("cannot handle this type -> {0}".format(values.dtype))
 
-        # Always convert inf to nan
-        values[np.isinf(values)] = np.NaN
+        # Convert inf to nan for C funcs
+        inf = np.isinf(values)
+        if inf.any():
+            values = np.where(inf, np.nan, values)
 
         return values
 


Test patch:
diff --git a/pandas/tests/window/test_rolling.py b/pandas/tests/window/test_rolling.py
--- a/pandas/tests/window/test_rolling.py
+++ b/pandas/tests/window/test_rolling.py
@@ -326,3 +326,11 @@ def test_rolling_axis_count(self, axis_frame):
 
         result = df.rolling(2, axis=axis_frame).count()
         tm.assert_frame_equal(result, expected)
+
+    def test_readonly_array(self):
+        # GH-27766
+        arr = np.array([1, 3, np.nan, 3, 5])
+        arr.setflags(write=False)
+        result = pd.Series(arr).rolling(2).mean()
+        expected = pd.Series([np.nan, 2, np.nan, np.nan, 4])
+        tm.assert_series_equal(result, expected)