mirror of
https://github.com/PiBrewing/craftbeerpi4.git
synced 2024-11-23 07:28:13 +01:00
181 lines
5.8 KiB
Python
181 lines
5.8 KiB
Python
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
|