Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions doc/source/whatsnew/v0.24.0.rst
Original file line number Diff line number Diff line change
Expand Up @@ -1003,6 +1003,7 @@ update the ``ExtensionDtype._metadata`` tuple to match the signature of your
- :meth:`Series.unstack` and :meth:`DataFrame.unstack` no longer convert extension arrays to object-dtype ndarrays. Each column in the output ``DataFrame`` will now have the same dtype as the input (:issue:`23077`).
- Bug when grouping :meth:`Dataframe.groupby()` and aggregating on ``ExtensionArray`` it was not returning the actual ``ExtensionArray`` dtype (:issue:`23227`).
- A default repr for :class:`ExtensionArray` is now provided (:issue:`23601`).
- Added `.size()` alias for `.count` function for `Window` (:issue:`24057`).

.. _whatsnew_0240.api.incompatibilities:

Expand Down
18 changes: 16 additions & 2 deletions pandas/_libs/window.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -353,12 +353,27 @@ def get_window_indexer(values, win, minp, index, closed,
right_closed, index, floor)
return indexer.get_data()

# Rolling size
def roll_size(ndarray[float64_t] values, int64_t win, int64_t minp,
object index, object closed):
cdef:
int64_t N
ndarray[int64_t] start, end
ndarray[float64_t] output

start, end, N, _, _, _ = get_window_indexer(values, win,
minp, index, closed)
output = np.empty(N, dtype=float)

output = (end - start).astype(float)

return output


# ----------------------------------------------------------------------
# Rolling count
# this is only an impl for index not None, IOW, freq aware


def roll_count(ndarray[float64_t] values, int64_t win, int64_t minp,
object index, object closed):
cdef:
Expand Down Expand Up @@ -408,7 +423,6 @@ def roll_count(ndarray[float64_t] values, int64_t win, int64_t minp,

return output


# ----------------------------------------------------------------------
# Rolling sum

Expand Down
20 changes: 20 additions & 0 deletions pandas/core/window.py
Original file line number Diff line number Diff line change
Expand Up @@ -943,6 +943,21 @@ def count(self):

return self._wrap_results(results, blocks, obj)

def size(self):
blocks, obj, index = self._create_blocks()
# Validate the index
self._get_index(index=index)

# window = self._get_window()
# window = min(window, len(obj)) if not self.center else window

results = []
for b in blocks:
results.append(b.size())

return self._wrap_results(results, blocks, obj)


_shared_docs['apply'] = dedent(r"""
%(name)s function apply.

Expand Down Expand Up @@ -1665,6 +1680,11 @@ def count(self):

return super(Rolling, self).count()

def size(self):
if self.is_freq_type:
return self._apply('roll_size', 'size')
return super(Rolling, self).size()

@Substitution(name='rolling')
@Appender(_doc_template)
@Appender(_shared_docs['apply'])
Expand Down
18 changes: 18 additions & 0 deletions pandas/tests/test_window.py
Original file line number Diff line number Diff line change
Expand Up @@ -646,6 +646,24 @@ def test_rolling_axis(self, axis_frame):
result = df.rolling(3, axis=axis_frame).sum()
tm.assert_frame_equal(result, expected)

def test_size(self):
# gh-24057
ser = Series(
np.random.rand(20),
index=pd.date_range('2012-1-1', periods=20)
)
ser.iloc[[5, -1]] = np.nan
ser.drop([pd.Timestamp('2012-1-10')], inplace=True) # drop element in the middle

window = ser.rolling('5D')

expected = window.agg(np.size)
keyword_agg = window.agg('size')
tm.assert_series_equal(keyword_agg, expected)

attribute_agg = window.size()
tm.assert_series_equal(attribute_agg, expected)


class TestExpanding(Base):

Expand Down