From 48a3224c875a8fe5d22a7f76014a936738397bd8 Mon Sep 17 00:00:00 2001 From: Hassan Kibirige Date: Wed, 17 Oct 2018 12:53:20 +0300 Subject: [PATCH] Prevent np.asarray from destroying series indices fixes has2k1/plotnine#210 --- doc/changelog.rst | 10 ++++++++++ mizani/bounds.py | 16 ++++++++++++---- mizani/tests/test_bounds.py | 20 ++++++++++++++++++++ mizani/tests/test_utils.py | 5 +++++ mizani/utils.py | 8 ++++++-- 5 files changed, 53 insertions(+), 6 deletions(-) diff --git a/doc/changelog.rst b/doc/changelog.rst index 126a146..f42e1ac 100644 --- a/doc/changelog.rst +++ b/doc/changelog.rst @@ -1,6 +1,16 @@ Changelog ========= +v0.5.2 +------ +*(2018-17-10)* + +Bug Fixes +********* + +- Fixed issue where some functions that took pandas series + would return output where the index did not match that of the input. + v0.5.1 ------ *(2018-15-10)* diff --git a/mizani/bounds.py b/mizani/bounds.py index 6912e4b..07c1c4d 100644 --- a/mizani/bounds.py +++ b/mizani/bounds.py @@ -107,7 +107,9 @@ def rescale_mid(x, to=(0, 1), _from=None, mid=0): array_like = False x = [x] - x = np.asarray(x) + if not hasattr(x, 'dtype'): + x = np.asarray(x) + if _from is None: _from = np.array([np.min(x), np.max(x)]) else: @@ -174,7 +176,9 @@ def rescale_max(x, to=(0, 1), _from=None): array_like = False x = [x] - x = np.asarray(x) + if not hasattr(x, 'dtype'): + x = np.asarray(x) + if _from is None: _from = np.array([np.min(x), np.max(x)]) @@ -210,7 +214,9 @@ def squish_infinite(x, range=(0, 1)): [0.0, -10.0, 0.5, 0.25, 9.0] """ xtype = type(x) - x = np.asarray(x) + + if not hasattr(x, 'dtype'): + x = np.asarray(x) x[x == -np.inf] = range[0] x[x == np.inf] = range[1] @@ -247,7 +253,9 @@ def squish(x, range=(0, 1), only_finite=True): [0.0, 0.0, 0.2, 0.5, 0.8, 1.0, 1.0] """ xtype = type(x) - x = np.asarray(x) + + if not hasattr(x, 'dtype'): + x = np.asarray(x) finite = np.isfinite(x) if only_finite else True diff --git a/mizani/tests/test_bounds.py b/mizani/tests/test_bounds.py index 6a2a569..a475a56 100644 --- a/mizani/tests/test_bounds.py +++ b/mizani/tests/test_bounds.py @@ -254,6 +254,11 @@ def test_rescale_max(): # branches # assert rescale_max(2, _from=(0, 10)) == 0.2 + # Maintains the same index + s = pd.Series([1, 2, 3], index=[3, 2, 1]) + result = rescale_max(s) + assert s.index.equals(result.index) + def test_rescale_mid(): a = [1, 2, 3] @@ -272,6 +277,11 @@ def test_rescale_mid(): rescale_mid([2], _from=(2, 2), to=(2, 2), mid=2), [2]) + # Maintains the same index + s = pd.Series([1, 2, 3], index=[3, 2, 1]) + result = rescale_mid(s, mid=1) + assert s.index.equals(result.index) + def test_squish_infinite(): a = [-np.inf, np.inf, -np.inf, np.inf] @@ -283,6 +293,11 @@ def test_squish_infinite(): npt.assert_allclose(squish_infinite(b, (1, 10)), [5, 1, 2, 3, 6]) + # Maintains the same index + s = pd.Series([1, 2, 3, 4], index=[4, 3, 2, 1]) + result = squish_infinite(s) + assert s.index.equals(result.index) + def test_squish(): a = [-np.inf, np.inf, -np.inf, np.inf] @@ -300,6 +315,11 @@ def test_squish(): [5, 1, 2, 3, 6]) npt.assert_allclose(squish(c, (1, 10)), c) + # Maintains the same index + s = pd.Series([.1, .2, .3, 9], index=[4, 3, 2, 1]) + result = squish(s) + assert s.index.equals(result.index) + def test_zero_range(): c = np.array diff --git a/mizani/tests/test_utils.py b/mizani/tests/test_utils.py index 59fd406..ce7fe6e 100644 --- a/mizani/tests/test_utils.py +++ b/mizani/tests/test_utils.py @@ -17,6 +17,11 @@ def test_round_any(): assert round_any(x, 5) == 5 assert round_any(x, 1.5) == 4.5 + # Maintains the same index + s = pd.Series([1.1, 2.2, 3.3], index=[3, 2, 1]) + result = round_any(s, 2) + assert s.index.equals(result.index) + def test_min_max(): x = [1, 2, 3, 4, 5] diff --git a/mizani/utils.py b/mizani/utils.py index 0f587bd..d3311af 100644 --- a/mizani/utils.py +++ b/mizani/utils.py @@ -44,7 +44,9 @@ def round_any(x, accuracy, f=np.round): """ Round to multiple of any number. """ - x = np.asarray(x) + if not hasattr(x, 'dtype'): + x = np.asarray(x) + return f(x / accuracy) * accuracy @@ -66,7 +68,9 @@ def min_max(x, na_rm=False, finite=True): out : tuple (minimum, maximum) of x """ - x = np.asarray(x) + if not hasattr(x, 'dtype'): + x = np.asarray(x) + if na_rm and finite: x = x[np.isfinite(x)] elif not na_rm and np.any(np.isnan(x)):