from operator import methodcaller import numpy as np import pytest import pandas as pd from pandas import MultiIndex, Series, date_range import pandas._testing as tm from .test_generic import Generic class TestSeries(Generic): _typ = Series _comparator = lambda self, x, y: tm.assert_series_equal(x, y) def test_rename_mi(self): s = Series( [11, 21, 31], index=MultiIndex.from_tuples([("A", x) for x in ["a", "B", "c"]]), ) s.rename(str.lower) @pytest.mark.parametrize("func", ["rename_axis", "_set_axis_name"]) def test_set_axis_name_mi(self, func): s = Series( [11, 21, 31], index=MultiIndex.from_tuples( [("A", x) for x in ["a", "B", "c"]], names=["l1", "l2"] ), ) result = methodcaller(func, ["L1", "L2"])(s) assert s.index.name is None assert s.index.names == ["l1", "l2"] assert result.index.name is None assert result.index.names, ["L1", "L2"] def test_set_axis_name_raises(self): s = pd.Series([1]) msg = "No axis named 1 for object type Series" with pytest.raises(ValueError, match=msg): s._set_axis_name(name="a", axis=1) def test_get_numeric_data_preserve_dtype(self): # get the numeric data o = Series([1, 2, 3]) result = o._get_numeric_data() self._compare(result, o) o = Series([1, "2", 3.0]) result = o._get_numeric_data() expected = Series([], dtype=object, index=pd.Index([], dtype=object)) self._compare(result, expected) o = Series([True, False, True]) result = o._get_numeric_data() self._compare(result, o) o = Series([True, False, True]) result = o._get_bool_data() self._compare(result, o) o = Series(date_range("20130101", periods=3)) result = o._get_numeric_data() expected = Series([], dtype="M8[ns]", index=pd.Index([], dtype=object)) self._compare(result, expected) def test_nonzero_single_element(self): # allow single item via bool method s = Series([True]) assert s.bool() s = Series([False]) assert not s.bool() msg = "The truth value of a Series is ambiguous" # single item nan to raise for s in [Series([np.nan]), Series([pd.NaT]), Series([True]), Series([False])]: with pytest.raises(ValueError, match=msg): bool(s) msg = "bool cannot act on a non-boolean single element Series" for s in [Series([np.nan]), Series([pd.NaT])]: with pytest.raises(ValueError, match=msg): s.bool() # multiple bool are still an error msg = "The truth value of a Series is ambiguous" for s in [Series([True, True]), Series([False, False])]: with pytest.raises(ValueError, match=msg): bool(s) with pytest.raises(ValueError, match=msg): s.bool() # single non-bool are an error for s in [Series([1]), Series([0]), Series(["a"]), Series([0.0])]: msg = "The truth value of a Series is ambiguous" with pytest.raises(ValueError, match=msg): bool(s) msg = "bool cannot act on a non-boolean single element Series" with pytest.raises(ValueError, match=msg): s.bool() def test_metadata_propagation_indiv(self): # check that the metadata matches up on the resulting ops o = Series(range(3), range(3)) o.name = "foo" o2 = Series(range(3), range(3)) o2.name = "bar" result = o.T self.check_metadata(o, result) # resample ts = Series( np.random.rand(1000), index=date_range("20130101", periods=1000, freq="s"), name="foo", ) result = ts.resample("1T").mean() self.check_metadata(ts, result) result = ts.resample("1T").min() self.check_metadata(ts, result) result = ts.resample("1T").apply(lambda x: x.sum()) self.check_metadata(ts, result) _metadata = Series._metadata _finalize = Series.__finalize__ Series._metadata = ["name", "filename"] o.filename = "foo" o2.filename = "bar" def finalize(self, other, method=None, **kwargs): for name in self._metadata: if method == "concat" and name == "filename": value = "+".join( [getattr(o, name) for o in other.objs if getattr(o, name, None)] ) object.__setattr__(self, name, value) else: object.__setattr__(self, name, getattr(other, name, None)) return self Series.__finalize__ = finalize result = pd.concat([o, o2]) assert result.filename == "foo+bar" assert result.name is None # reset Series._metadata = _metadata Series.__finalize__ = _finalize # FIXME: use monkeypatch class TestSeries2: # Separating off because it doesnt rely on parent class @pytest.mark.parametrize( "s", [ Series([np.arange(5)]), pd.date_range("1/1/2011", periods=24, freq="H"), pd.Series(range(5), index=pd.date_range("2017", periods=5)), ], ) @pytest.mark.parametrize("shift_size", [0, 1, 2]) def test_shift_always_copy(self, s, shift_size): # GH22397 assert s.shift(shift_size) is not s @pytest.mark.parametrize("move_by_freq", [pd.Timedelta("1D"), pd.Timedelta("1M")]) def test_datetime_shift_always_copy(self, move_by_freq): # GH22397 s = pd.Series(range(5), index=pd.date_range("2017", periods=5)) assert s.shift(freq=move_by_freq) is not s