Updated script that can be controled by Nodejs web app
This commit is contained in:
@@ -0,0 +1,258 @@
|
||||
import numpy as np
|
||||
import pytest
|
||||
|
||||
from pandas import (
|
||||
Categorical,
|
||||
DataFrame,
|
||||
Index,
|
||||
Series,
|
||||
Timestamp,
|
||||
date_range,
|
||||
period_range,
|
||||
timedelta_range,
|
||||
)
|
||||
import pandas._testing as tm
|
||||
from pandas.core.arrays.categorical import CategoricalAccessor
|
||||
from pandas.core.indexes.accessors import Properties
|
||||
|
||||
|
||||
class TestCatAccessor:
|
||||
@pytest.mark.parametrize(
|
||||
"method",
|
||||
[
|
||||
lambda x: x.cat.set_categories([1, 2, 3]),
|
||||
lambda x: x.cat.reorder_categories([2, 3, 1], ordered=True),
|
||||
lambda x: x.cat.rename_categories([1, 2, 3]),
|
||||
lambda x: x.cat.remove_unused_categories(),
|
||||
lambda x: x.cat.remove_categories([2]),
|
||||
lambda x: x.cat.add_categories([4]),
|
||||
lambda x: x.cat.as_ordered(),
|
||||
lambda x: x.cat.as_unordered(),
|
||||
],
|
||||
)
|
||||
def test_getname_categorical_accessor(self, method):
|
||||
# GH#17509
|
||||
ser = Series([1, 2, 3], name="A").astype("category")
|
||||
expected = "A"
|
||||
result = method(ser).name
|
||||
assert result == expected
|
||||
|
||||
def test_cat_accessor(self):
|
||||
ser = Series(Categorical(["a", "b", np.nan, "a"]))
|
||||
tm.assert_index_equal(ser.cat.categories, Index(["a", "b"]))
|
||||
assert not ser.cat.ordered, False
|
||||
|
||||
exp = Categorical(["a", "b", np.nan, "a"], categories=["b", "a"])
|
||||
|
||||
res = ser.cat.set_categories(["b", "a"])
|
||||
tm.assert_categorical_equal(res.values, exp)
|
||||
|
||||
ser[:] = "a"
|
||||
ser = ser.cat.remove_unused_categories()
|
||||
tm.assert_index_equal(ser.cat.categories, Index(["a"]))
|
||||
|
||||
def test_cat_accessor_api(self):
|
||||
# GH#9322
|
||||
|
||||
assert Series.cat is CategoricalAccessor
|
||||
ser = Series(list("aabbcde")).astype("category")
|
||||
assert isinstance(ser.cat, CategoricalAccessor)
|
||||
|
||||
invalid = Series([1])
|
||||
with pytest.raises(AttributeError, match="only use .cat accessor"):
|
||||
invalid.cat
|
||||
assert not hasattr(invalid, "cat")
|
||||
|
||||
def test_cat_accessor_no_new_attributes(self):
|
||||
# https://github.com/pandas-dev/pandas/issues/10673
|
||||
cat = Series(list("aabbcde")).astype("category")
|
||||
with pytest.raises(AttributeError, match="You cannot add any new attribute"):
|
||||
cat.cat.xlabel = "a"
|
||||
|
||||
def test_categorical_delegations(self):
|
||||
# invalid accessor
|
||||
msg = r"Can only use \.cat accessor with a 'category' dtype"
|
||||
with pytest.raises(AttributeError, match=msg):
|
||||
Series([1, 2, 3]).cat
|
||||
with pytest.raises(AttributeError, match=msg):
|
||||
Series([1, 2, 3]).cat()
|
||||
with pytest.raises(AttributeError, match=msg):
|
||||
Series(["a", "b", "c"]).cat
|
||||
with pytest.raises(AttributeError, match=msg):
|
||||
Series(np.arange(5.0)).cat
|
||||
with pytest.raises(AttributeError, match=msg):
|
||||
Series([Timestamp("20130101")]).cat
|
||||
|
||||
# Series should delegate calls to '.categories', '.codes', '.ordered'
|
||||
# and the methods '.set_categories()' 'drop_unused_categories()' to the
|
||||
# categorical
|
||||
ser = Series(Categorical(["a", "b", "c", "a"], ordered=True))
|
||||
exp_categories = Index(["a", "b", "c"])
|
||||
tm.assert_index_equal(ser.cat.categories, exp_categories)
|
||||
ser = ser.cat.rename_categories([1, 2, 3])
|
||||
exp_categories = Index([1, 2, 3])
|
||||
tm.assert_index_equal(ser.cat.categories, exp_categories)
|
||||
|
||||
exp_codes = Series([0, 1, 2, 0], dtype="int8")
|
||||
tm.assert_series_equal(ser.cat.codes, exp_codes)
|
||||
|
||||
assert ser.cat.ordered
|
||||
ser = ser.cat.as_unordered()
|
||||
assert not ser.cat.ordered
|
||||
|
||||
ser = ser.cat.as_ordered()
|
||||
assert ser.cat.ordered
|
||||
|
||||
# reorder
|
||||
ser = Series(Categorical(["a", "b", "c", "a"], ordered=True))
|
||||
exp_categories = Index(["c", "b", "a"])
|
||||
exp_values = np.array(["a", "b", "c", "a"], dtype=np.object_)
|
||||
ser = ser.cat.set_categories(["c", "b", "a"])
|
||||
tm.assert_index_equal(ser.cat.categories, exp_categories)
|
||||
tm.assert_numpy_array_equal(ser.values.__array__(), exp_values)
|
||||
tm.assert_numpy_array_equal(ser.__array__(), exp_values)
|
||||
|
||||
# remove unused categories
|
||||
ser = Series(Categorical(["a", "b", "b", "a"], categories=["a", "b", "c"]))
|
||||
exp_categories = Index(["a", "b"])
|
||||
exp_values = np.array(["a", "b", "b", "a"], dtype=np.object_)
|
||||
ser = ser.cat.remove_unused_categories()
|
||||
tm.assert_index_equal(ser.cat.categories, exp_categories)
|
||||
tm.assert_numpy_array_equal(ser.values.__array__(), exp_values)
|
||||
tm.assert_numpy_array_equal(ser.__array__(), exp_values)
|
||||
|
||||
# This method is likely to be confused, so test that it raises an error
|
||||
# on wrong inputs:
|
||||
msg = "'Series' object has no attribute 'set_categories'"
|
||||
with pytest.raises(AttributeError, match=msg):
|
||||
ser.set_categories([4, 3, 2, 1])
|
||||
|
||||
# right: ser.cat.set_categories([4,3,2,1])
|
||||
|
||||
# GH#18862 (let Series.cat.rename_categories take callables)
|
||||
ser = Series(Categorical(["a", "b", "c", "a"], ordered=True))
|
||||
result = ser.cat.rename_categories(lambda x: x.upper())
|
||||
expected = Series(
|
||||
Categorical(["A", "B", "C", "A"], categories=["A", "B", "C"], ordered=True)
|
||||
)
|
||||
tm.assert_series_equal(result, expected)
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"idx",
|
||||
[
|
||||
date_range("1/1/2015", periods=5),
|
||||
date_range("1/1/2015", periods=5, tz="MET"),
|
||||
period_range("1/1/2015", freq="D", periods=5),
|
||||
timedelta_range("1 days", "10 days"),
|
||||
],
|
||||
)
|
||||
def test_dt_accessor_api_for_categorical(self, idx):
|
||||
# https://github.com/pandas-dev/pandas/issues/10661
|
||||
|
||||
ser = Series(idx)
|
||||
cat = ser.astype("category")
|
||||
|
||||
# only testing field (like .day)
|
||||
# and bool (is_month_start)
|
||||
attr_names = type(ser._values)._datetimelike_ops
|
||||
|
||||
assert isinstance(cat.dt, Properties)
|
||||
|
||||
special_func_defs = [
|
||||
("strftime", ("%Y-%m-%d",), {}),
|
||||
("round", ("D",), {}),
|
||||
("floor", ("D",), {}),
|
||||
("ceil", ("D",), {}),
|
||||
("asfreq", ("D",), {}),
|
||||
("as_unit", ("s"), {}),
|
||||
]
|
||||
if idx.dtype == "M8[ns]":
|
||||
# exclude dt64tz since that is already localized and would raise
|
||||
tup = ("tz_localize", ("UTC",), {})
|
||||
special_func_defs.append(tup)
|
||||
elif idx.dtype.kind == "M":
|
||||
# exclude dt64 since that is not localized so would raise
|
||||
tup = ("tz_convert", ("EST",), {})
|
||||
special_func_defs.append(tup)
|
||||
|
||||
_special_func_names = [f[0] for f in special_func_defs]
|
||||
|
||||
_ignore_names = ["components", "tz_localize", "tz_convert"]
|
||||
|
||||
func_names = [
|
||||
fname
|
||||
for fname in dir(ser.dt)
|
||||
if not (
|
||||
fname.startswith("_")
|
||||
or fname in attr_names
|
||||
or fname in _special_func_names
|
||||
or fname in _ignore_names
|
||||
)
|
||||
]
|
||||
|
||||
func_defs = [(fname, (), {}) for fname in func_names]
|
||||
func_defs.extend(
|
||||
f_def for f_def in special_func_defs if f_def[0] in dir(ser.dt)
|
||||
)
|
||||
|
||||
for func, args, kwargs in func_defs:
|
||||
warn_cls = []
|
||||
if func == "to_period" and getattr(idx, "tz", None) is not None:
|
||||
# dropping TZ
|
||||
warn_cls.append(UserWarning)
|
||||
if func == "to_pydatetime":
|
||||
# deprecated to return Index[object]
|
||||
warn_cls.append(FutureWarning)
|
||||
if warn_cls:
|
||||
warn_cls = tuple(warn_cls)
|
||||
else:
|
||||
warn_cls = None
|
||||
with tm.assert_produces_warning(warn_cls):
|
||||
res = getattr(cat.dt, func)(*args, **kwargs)
|
||||
exp = getattr(ser.dt, func)(*args, **kwargs)
|
||||
|
||||
tm.assert_equal(res, exp)
|
||||
|
||||
for attr in attr_names:
|
||||
res = getattr(cat.dt, attr)
|
||||
exp = getattr(ser.dt, attr)
|
||||
|
||||
tm.assert_equal(res, exp)
|
||||
|
||||
def test_dt_accessor_api_for_categorical_invalid(self):
|
||||
invalid = Series([1, 2, 3]).astype("category")
|
||||
msg = "Can only use .dt accessor with datetimelike"
|
||||
|
||||
with pytest.raises(AttributeError, match=msg):
|
||||
invalid.dt
|
||||
assert not hasattr(invalid, "str")
|
||||
|
||||
def test_set_categories_setitem(self):
|
||||
# GH#43334
|
||||
|
||||
df = DataFrame({"Survived": [1, 0, 1], "Sex": [0, 1, 1]}, dtype="category")
|
||||
|
||||
df["Survived"] = df["Survived"].cat.rename_categories(["No", "Yes"])
|
||||
df["Sex"] = df["Sex"].cat.rename_categories(["female", "male"])
|
||||
|
||||
# values should not be coerced to NaN
|
||||
assert list(df["Sex"]) == ["female", "male", "male"]
|
||||
assert list(df["Survived"]) == ["Yes", "No", "Yes"]
|
||||
|
||||
df["Sex"] = Categorical(df["Sex"], categories=["female", "male"], ordered=False)
|
||||
df["Survived"] = Categorical(
|
||||
df["Survived"], categories=["No", "Yes"], ordered=False
|
||||
)
|
||||
|
||||
# values should not be coerced to NaN
|
||||
assert list(df["Sex"]) == ["female", "male", "male"]
|
||||
assert list(df["Survived"]) == ["Yes", "No", "Yes"]
|
||||
|
||||
def test_categorical_of_booleans_is_boolean(self):
|
||||
# https://github.com/pandas-dev/pandas/issues/46313
|
||||
df = DataFrame(
|
||||
{"int_cat": [1, 2, 3], "bool_cat": [True, False, False]}, dtype="category"
|
||||
)
|
||||
value = df["bool_cat"].cat.categories.dtype
|
||||
expected = np.dtype(np.bool_)
|
||||
assert value is expected
|
||||
Reference in New Issue
Block a user