diff --git a/leanframe/core/series.py b/leanframe/core/series.py index 8547185..b898010 100644 --- a/leanframe/core/series.py +++ b/leanframe/core/series.py @@ -94,6 +94,33 @@ def __mul__(self, other) -> Series: def __rmul__(self, other) -> Series: return Series(getattr(other, "_data", other) * self._data) + def __round__(self, n) -> Series: + return Series(self._data.round(n)) + + def sum(self): + """Return the sum of the Series.""" + return self._data.sum().to_pyarrow().as_py() + + def mean(self): + """Return the mean of the Series.""" + return self._data.mean().to_pyarrow().as_py() + + def min(self): + """Return the min of the Series.""" + return self._data.min().to_pyarrow().as_py() + + def max(self): + """Return the max of the Series.""" + return self._data.max().to_pyarrow().as_py() + + def std(self): + """Return the std of the Series.""" + return self._data.std().to_pyarrow().as_py() + + def var(self): + """Return the var of the Series.""" + return self._data.var().to_pyarrow().as_py() + def copy(self) -> Series: """Return a copy of the Series.""" return Series(self._data) diff --git a/specs/2025-09-16-series-methods.md b/specs/2025-09-16-series-methods.md index 917a1c3..5213316 100644 --- a/specs/2025-09-16-series-methods.md +++ b/specs/2025-09-16-series-methods.md @@ -72,7 +72,7 @@ and check off the item with an x. - [ ] pandas.Series.rpow - [ ] pandas.Series.combine - [ ] pandas.Series.combine_first -- [ ] pandas.Series.round +- [x] pandas.Series.round - [ ] pandas.Series.lt - [ ] pandas.Series.gt - [ ] pandas.Series.le @@ -108,10 +108,10 @@ and check off the item with an x. - [ ] pandas.Series.diff - [ ] pandas.Series.factorize - [ ] pandas.Series.kurt -- [ ] pandas.Series.max -- [ ] pandas.Series.mean +- [x] pandas.Series.max +- [x] pandas.Series.mean - [ ] pandas.Series.median -- [ ] pandas.Series.min +- [x] pandas.Series.min - [ ] pandas.Series.mode - [ ] pandas.Series.nlargest - [ ] pandas.Series.nsmallest @@ -121,9 +121,9 @@ and check off the item with an x. - [ ] pandas.Series.rank - [ ] pandas.Series.sem - [ ] pandas.Series.skew -- [ ] pandas.Series.std -- [ ] pandas.Series.sum -- [ ] pandas.Series.var +- [x] pandas.Series.std +- [x] pandas.Series.sum +- [x] pandas.Series.var - [ ] pandas.Series.kurtosis - [ ] pandas.Series.unique - [ ] pandas.Series.nunique diff --git a/tests/unit/test_series.py b/tests/unit/test_series.py index bc4d60c..9abe56b 100644 --- a/tests/unit/test_series.py +++ b/tests/unit/test_series.py @@ -38,6 +38,17 @@ def series_for_properties(session): return df_lf["int_col"], df_lf["float_col"] +@pytest.fixture +def numeric_series(session): + df_pd = pd.DataFrame( + { + "a": [1, 2, 3, 4, 5], + "b": [1.1, 2.2, 3.3, 4.4, 5.5], + } + ) + return session.DataFrame(df_pd) + + def test_series_ndim(series_for_properties): series_int, series_float = series_for_properties assert series_int.ndim == 1 @@ -189,6 +200,52 @@ def test_series_arithmetic_scalar(session, op, other, expected_data): ) +def test_series_round(numeric_series): + series = numeric_series["b"] + result = round(series, 0) + expected = pd.Series( + [1.0, 2.0, 3.0, 4.0, 6.0], + dtype=pd.ArrowDtype(pa.float64()), + ) + result_pd = result.to_pandas() + result_pd = result_pd.astype(pd.ArrowDtype(pa.float64())) + pd.testing.assert_series_equal( + result_pd, + expected, + check_names=False, + ) + + +def test_series_sum(numeric_series): + series = numeric_series["a"] + assert series.sum() == 15 + + +def test_series_mean(numeric_series): + series = numeric_series["a"] + assert series.mean() == 3.0 + + +def test_series_min(numeric_series): + series = numeric_series["a"] + assert series.min() == 1 + + +def test_series_max(numeric_series): + series = numeric_series["a"] + assert series.max() == 5 + + +def test_series_std(numeric_series): + series = numeric_series["b"] + assert round(series.std(), 2) == 1.74 + + +def test_series_var(numeric_series): + series = numeric_series["b"] + assert round(series.var(), 2) == 3.03 + + def test_series_copy(session): df_pd = pd.DataFrame({"col1": [1, 2, 3]}) df_lf = session.DataFrame(df_pd)