Skip to content

BUG: COMPAT:0.18 added scipy version check GH12887 #13007

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 9 commits into from
Closed

BUG: COMPAT:0.18 added scipy version check GH12887 #13007

wants to merge 9 commits into from

Conversation

jmwoloso
Copy link

@jmwoloso jmwoloso commented Apr 27, 2016

'piecewise_polynomial': interpolate.piecewise_polynomial_interpolate,
}
import scipy
if scipy.__version__ <= '0.17':
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you move this up to be with the from scipy import interpolate and assign a variable like scipy_version = scipy.__version__. Then your if block would me if LooseVersion(scipy_version) <= LooseVersion('0.17'):, where LooseVersion comese from distutils.version.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also, maybe start with

alt_methods = {
      'barycentric': interpolate.barycentric_interpolate,
      'krogh': interpolate.krogh_interpolate,
}

and then do your if block checking the version. That way you aren't repeating the other two methods.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually, why don't use just start with

alt_methods = {
      'barycentric': interpolate.barycentric_interpolate,
      'krogh': interpolate.krogh_interpolate,
      'from_derivatives': interpolate.BPoly.from_derivatives`,
}

and then only add piecewise_polynomial if the scipy version is less than 0.18. That way people can write code that is compatible with both versions of scipy.

@TomAugspurger
Copy link
Contributor

Could you also add a test in pandas/tests/test_generic for this? Apparently we don't have any that hit piecewise_polynomial directly. The behavior should be

  • pandas 0.18.1, scipy <= 0.17: piecewise_polynomial continues to work, from_derivatives now works too
  • pandas 0.18.1, scipy > 0.17: piecewise_polynomial fails (scipy's error) from_derivatives works

@TomAugspurger TomAugspurger added the Missing-data np.nan, pd.NaT, pd.NA, dropna, isnull, interpolate label Apr 27, 2016
@TomAugspurger TomAugspurger added this to the 0.18.1 milestone Apr 27, 2016
@TomAugspurger TomAugspurger added the Compat pandas objects compatability with Numpy or Python functions label Apr 27, 2016
@@ -3455,7 +3455,7 @@ def replace(self, to_replace=None, value=None, inplace=False, limit=None,
----------
method : {'linear', 'time', 'index', 'values', 'nearest', 'zero',
'slinear', 'quadratic', 'cubic', 'barycentric', 'krogh',
'polynomial', 'spline' 'piecewise_polynomial', 'pchip',
'polynomial', 'spline' 'from_derivatives', 'pchip',
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we need to leave the original method piecewise_polynomial and add the new one from_derivatives. Then switch using the version of scipy. E.g. if > 0.17 and piecewise_polynomila -> from_derivatives. If passed from_derivatives I would just use it.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So we need a check near the top of interpolate in pandas.core.generic as well right?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

no all of this validation stuff is in core/missing.py. all we need here is a doc note. e.g. versionadded 0.18.1 -> from_derivates (and how scipy < 0.18.0) works with this.

@jreback
Copy link
Contributor

jreback commented Apr 27, 2016

we need a test to assert all of this stuff. put in test_generic where the rest of the interpolation stuff already is.

@jmwoloso
Copy link
Author

I'll incorporate all of this. Thanks for the feedback thus far!

@jmwoloso
Copy link
Author

I'll write the tests once I get the 'okay' on missing.py and generic.py code is acceptable. Looking forward to both of your comments on these latest commits. I'll squash everything down once I get it all wrapped up.

@jreback
Copy link
Contributor

jreback commented Apr 28, 2016

always write tests first! that way can validate you are testing the right thing

if method == 'piecewise_polynomial' and LooseVersion(scipy_version) > \
LooseVersion('0.17'):
raise ValueError("Method '{0}' is deprecated for Scipy > 0.17. "
"Use 'from_derivatives' instead".format(method))
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I raise a ValueError here, however it is isn't propagated back up to the calling function interpolate from pandas/core/internals.py, so open to suggestions assuming this approach is correct to handling it.

@jmwoloso
Copy link
Author

You're right, should have started there. I'll get to work on those.


.. versionadded:: 0.18.1
Added support for the 'akima' method
Added interpolate method 'from_derivatives' which replaces
'piecewise_polynomial' in scipy 0.18; backwards-compatible with
scipy < 0.18
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

good

@jreback
Copy link
Contributor

jreback commented Apr 30, 2016

@jmwoloso can you update

@jmwoloso
Copy link
Author

jmwoloso commented May 1, 2016

Update to the most recent pandas dev you mean?

@jreback
Copy link
Contributor

jreback commented May 1, 2016

yep

@jmwoloso
Copy link
Author

jmwoloso commented May 1, 2016

Sure thing. Away from my comp currently but will do when I get back.

@@ -516,3 +516,4 @@ Bug Fixes
- Bug in ``.describe()`` resets categorical columns information (:issue:`11558`)
- Bug where ``loffset`` argument was not applied when calling ``resample().count()`` on a timeseries (:issue:`12725`)
- ``pd.read_excel()`` now accepts column names associated with keyword argument ``names``(:issue:`12870`)
- Compat with SciPy > 0.17 for deprecated 'piecewise_polynomial' interpolation method (:issue:`12887`)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

put this in Other API changes section. Add a line in Enhancements for the addition of from_derivatives method as well (you can use the PR number there).

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done and done.

@jreback
Copy link
Contributor

jreback commented May 1, 2016

Here's a patch which makes this clean. Just needs tests.

diff --git a/doc/source/whatsnew/v0.18.1.txt b/doc/source/whatsnew/v0.18.1.txt
index 4b1326a..0ca6683 100644
--- a/doc/source/whatsnew/v0.18.1.txt
+++ b/doc/source/whatsnew/v0.18.1.txt
@@ -512,6 +512,7 @@ Other API changes
 - Provide a proper ``__name__`` and ``__qualname__`` attributes for generic functions (:issue:`12021`)
 - ``pd.concat(ignore_index=True)`` now uses ``RangeIndex`` as default (:issue:`12695`)
 - ``pd.merge()`` and ``DataFrame.join()`` will show a ``UserWarning`` when merging/joining a single- with a multi-leveled dataframe (:issue:`9455`, :issue:`12219`)
+- Compat with SciPy > 0.17 for deprecated ``piecewise_polynomial`` interpolation method (:issue:`12887`)

 .. _whatsnew_0181.deprecations:

@@ -656,5 +657,3 @@ Bug Fixes
 - Bug in ``to_numeric`` with ``Index`` returns ``np.ndarray``, rather than ``Index`` (:issue:`12777`)
 - Bug in ``to_numeric`` with datetime-like may raise ``TypeError`` (:issue:`12777`)
 - Bug in ``to_numeric`` with scalar raises ``ValueError`` (:issue:`12777`)
-- ``pd.read_excel()`` now accepts column names associated with keyword argument ``names``(:issue:`12870`)
-- Compat with SciPy > 0.17 for deprecated 'piecewise_polynomial' interpolation method (:issue:`12887`)
diff --git a/pandas/core/missing.py b/pandas/core/missing.py
index c67fc78..0bf112d 100644
--- a/pandas/core/missing.py
+++ b/pandas/core/missing.py
@@ -83,8 +83,6 @@ def clean_fill_method(method, allow_nearest=False):


 def clean_interp_method(method, **kwargs):
-    import scipy
-    scipy_version = scipy.__version__
     order = kwargs.get('order')
     valid = ['linear', 'time', 'index', 'values', 'nearest', 'zero', 'slinear',
              'quadratic', 'cubic', 'barycentric', 'polynomial', 'krogh',
@@ -96,11 +94,7 @@ def clean_interp_method(method, **kwargs):
     if method not in valid:
         raise ValueError("method must be one of {0}."
                          "Got '{1}' instead.".format(valid, method))
-    # compat GH12887
-    if method == 'piecewise_polynomial' and LooseVersion(scipy_version) > \
-            LooseVersion('0.17'):
-        raise ValueError("Method '{0}' is deprecated for Scipy > 0.17. "
-                         "Use 'from_derivatives' instead".format(method))
+
     return method


@@ -200,7 +194,8 @@ def interpolate_1d(xvalues, yvalues, method='linear', limit=None,

     sp_methods = ['nearest', 'zero', 'slinear', 'quadratic', 'cubic',
                   'barycentric', 'krogh', 'spline', 'polynomial',
-                  'piecewise_polynomial', 'pchip', 'akima']
+                  'from_derivatives', 'piecewise_polynomial', 'pchip', 'akima']
+
     if method in sp_methods:
         inds = np.asarray(xvalues)
         # hack for DatetimeIndex, #1646
@@ -233,7 +228,6 @@ def _interpolate_scipy_wrapper(x, y, new_x, method, fill_value=None,
         raise ImportError('{0} interpolation requires Scipy'.format(method))

     new_x = np.asarray(new_x)
-    scipy_version = scipy.__version__  # for version check; GH12887

     # ignores some kwargs that could be passed along.
     alt_methods = {
@@ -259,13 +253,13 @@ def _interpolate_scipy_wrapper(x, y, new_x, method, fill_value=None,
         except ImportError:
             raise ImportError("Your version of Scipy does not support "
                               "Akima interpolation.")
-    elif method == 'piecewise_polynomial':  # GH12887
-        if LooseVersion(scipy_version) > LooseVersion('0.17'):
-            raise ValueError("Method '{0}' is deprecated for Scipy > 0.17. "
-                             "Use 'from_derivatives' instead".format(method))
+    elif method == 'piecewise_polynomial':
+        """ return the method for compat with scipy version """
+        if LooseVersion(scipy.__version__) <= LooseVersion('0.17'):
+            f = 'piecewise_polynomial_interpolate'
         else:
-            alt_methods['piecewise_polynomial'] = \
-                interpolate.piecewise_polynomial_interpolate
+            f = 'from_derivatives'
+        alt_methods['piecewise_polynomial'] = getattr(interpolate, f)

     interp1d_methods = ['nearest', 'zero', 'slinear', 'quadratic', 'cubic',
                         'polynomial']

@jreback
Copy link
Contributor

jreback commented May 1, 2016

jreback@31e01ae

Jason Wolosonovich and others added 5 commits May 1, 2016 11:24
added scipy version check to _interpolate_scipy_wrapper to handle deprecation of 'piecewise_polynomial' method for scipy > 0.17

CLN: added 'from_derivatives' to 'replace' docs in pandas.core.generic GH12887

added 'from_derivatives' to 'replace._shared_docs' and noted deprecation of 'piecewise_polynomial' method

DOC: referenced compatibility fix in 'whatsnew' docs
@jreback
Copy link
Contributor

jreback commented May 2, 2016

xref #13055 moved interpolation tests to a better location.

added scipy version check to _interpolate_scipy_wrapper to handle deprecation of 'piecewise_polynomial' method for scipy > 0.17

CLN: added 'from_derivatives' to 'replace' docs in pandas.core.generic GH12887

added 'from_derivatives' to 'replace._shared_docs' and noted deprecation of 'piecewise_polynomial' method

DOC: referenced compatibility fix in 'whatsnew' docs
@jreback
Copy link
Contributor

jreback commented May 2, 2016

ok here's a working / tested branch: https://github.com/jreback/pandas/tree/jmwoloso-compat_12887

though the tests work, they don't really exercise this too much (as they same results as using akima). this this is a very simple interp problem though.

@jmwoloso
Copy link
Author

jmwoloso commented May 2, 2016

Quick question. Should I be using the latest dev branch of scipy and numpy while I'm doing this or perhaps the latest stable releases of each? I'm currently using

>>> scipy.__version__
'0.18.0.dev0+609facc'
>>> numpy.__version__
'1.12.0.dev0+47b6c2b'

I ask because after applying your patch, I get an AttributeError when calling interpolate with method='piecewise_polynomial'. To fix that, I change line 262 in pandas.core.missing from:

alt_methods['piecewise_polynomial'] = getattr(interpolate, f)

to

alt_methods['piecewise_polynomial'] = getattr(interpolate.BPoly, f)

This change takes care of the AttributeError, which, I'm guessing was occurring because BPoly.from_derivatives is a class method(?)

However, it then raises an error mentioning the expected shape of y:

>>> import pandas as pd; import numpy as np
>>> s = pd.Series([0, np.nan, 2])
>>> s.interpolate(method='piecewise_polynomial')
Traceback (most recent call last):
  File "/home/jason/.virtualenvs/pandas_dev/lib/python3.4/site-packages/scipy/interpolate/interpolate.py", line 1452, in from_derivatives
    k = max(len(yi[i]) + len(yi[i+1]) for i in range(m))
  File "/home/jason/.virtualenvs/pandas_dev/lib/python3.4/site-packages/scipy/interpolate/interpolate.py", line 1452, in <genexpr>
    k = max(len(yi[i]) + len(yi[i+1]) for i in range(m))
TypeError: object of type 'numpy.float64' has no len()

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/home/jason/source/dev/pandas-jmwoloso/pandas/core/generic.py", line 3576, in interpolate
    **kwargs)
  File "/home/jason/source/dev/pandas-jmwoloso/pandas/core/internals.py", line 2926, in interpolate
    return self.apply('interpolate', **kwargs)
  File "/home/jason/source/dev/pandas-jmwoloso/pandas/core/internals.py", line 2890, in apply
    applied = getattr(b, f)(**kwargs)
  File "/home/jason/source/dev/pandas-jmwoloso/pandas/core/internals.py", line 906, in interpolate
    downcast=downcast, mgr=mgr, **kwargs)
  File "/home/jason/source/dev/pandas-jmwoloso/pandas/core/internals.py", line 969, in _interpolate
    interp_values = np.apply_along_axis(func, axis, data)
  File "/home/jason/.virtualenvs/pandas_dev/lib/python3.4/site-packages/numpy/lib/shape_base.py", line 91, in apply_along_axis
    res = func1d(arr[tuple(i.tolist())], *args, **kwargs)
  File "/home/jason/source/dev/pandas-jmwoloso/pandas/core/internals.py", line 966, in func
    bounds_error=False, **kwargs)
  File "/home/jason/source/dev/pandas-jmwoloso/pandas/core/missing.py", line 210, in interpolate_1d
    order=order, **kwargs)
  File "/home/jason/source/dev/pandas-jmwoloso/pandas/core/missing.py", line 288, in _interpolate_scipy_wrapper
    new_y = method(x, y, new_x, **kwargs)
  File "/home/jason/.virtualenvs/pandas_dev/lib/python3.4/site-packages/scipy/interpolate/interpolate.py", line 1454, in from_derivatives
    raise ValueError("Using a 1D array for y? Please .reshape(-1, 1).")
ValueError: Using a 1D array for y? Please .reshape(-1, 1).

@jreback
Copy link
Contributor

jreback commented May 2, 2016

make sure you have the latest pull of my branch

it works on all versions of scipy and numpy (that code is a previous version)

@jmwoloso
Copy link
Author

jmwoloso commented May 2, 2016

Ok, will do. I was going crazy for minute...

@jmwoloso
Copy link
Author

jmwoloso commented May 3, 2016

Pulled down your branch and merged it with mine, though I'm still getting the same errors when using method='piecewise_polynomial' BUT method='from_derivatives' works as expected.

>>> import pandas as pd;import numpy as np
>>> s = pd.Series([0, np.nan, 2])
>>> s.interpolate(method='from_derivatives')
0    0.0
1    1.0
2    2.0
dtype: float64
>>> s.interpolate(method='piecewise_polynomial')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/home/jason/source/dev/pandas-jmwoloso/pandas/core/generic.py", line 3576, in interpolate
    **kwargs)
  File "/home/jason/source/dev/pandas-jmwoloso/pandas/core/internals.py", line 2926, in interpolate
    return self.apply('interpolate', **kwargs)
  File "/home/jason/source/dev/pandas-jmwoloso/pandas/core/internals.py", line 2890, in apply
    applied = getattr(b, f)(**kwargs)
  File "/home/jason/source/dev/pandas-jmwoloso/pandas/core/internals.py", line 906, in interpolate
    downcast=downcast, mgr=mgr, **kwargs)
  File "/home/jason/source/dev/pandas-jmwoloso/pandas/core/internals.py", line 969, in _interpolate
    interp_values = np.apply_along_axis(func, axis, data)
  File "/home/jason/.virtualenvs/pandas_dev/lib/python3.4/site-packages/numpy/lib/shape_base.py", line 91, in apply_along_axis
    res = func1d(arr[tuple(i.tolist())], *args, **kwargs)
  File "/home/jason/source/dev/pandas-jmwoloso/pandas/core/internals.py", line 966, in func
    bounds_error=False, **kwargs)
  File "/home/jason/source/dev/pandas-jmwoloso/pandas/core/missing.py", line 210, in interpolate_1d
    order=order, **kwargs)
  File "/home/jason/source/dev/pandas-jmwoloso/pandas/core/missing.py", line 263, in _interpolate_scipy_wrapper
    alt_methods['piecewise_polynomial'] = getattr(interpolate, f)
AttributeError: 'module' object has no attribute 'from_derivatives'

I must be doing something wrong, but git says I'm up to date:

git pull https://github.com/jreback/pandas.git jmwoloso-compat_12887
From https://github.com/jreback/pandas
* branch            jmwoloso-compat_12887 -> FETCH_HEAD
Already up-to-date.

@jreback
Copy link
Contributor

jreback commented May 3, 2016

push up your changes and I'll look

@jmwoloso
Copy link
Author

jmwoloso commented May 3, 2016

Just pushed them. I did have a merge conflict that I had to fix, I was using getattr(interpolate.BPoly, f) in the alt_methods assignment in _interpolate_scipy_wrapper before in order to get it to use from_derivatives. Which then caused the shape error, but I see you've fixed that with the _from_derivatives convenience function which is good. I was going to tackle that, but I never use these interpolation methods, so it definitely would have taken me longer to figure out what it was expecting exactly.

@jreback
Copy link
Contributor

jreback commented May 3, 2016

yeah it looks like you have some older code here.

@jreback
Copy link
Contributor

jreback commented May 3, 2016

I am going to merge the branch I had earlier. Would appreciate if you can push some better tests though.

@jmwoloso
Copy link
Author

jmwoloso commented May 3, 2016

Yeah, I'll try rebasing with master again as well, I don't have pandas.tests.test_missing at all and I should

@jreback jreback closed this in c6110e2 May 3, 2016
@jreback
Copy link
Contributor

jreback commented May 3, 2016

@jmwoloso sorry for the rush on this. trying to get the release out the door tomorrow :).

If you can push some tests that would be great (no big hurry on those though).

@jmwoloso
Copy link
Author

jmwoloso commented May 3, 2016

Understand completely. I appreciate the help. I'll get those tests pushed once I see what you've written already for them.

@jreback
Copy link
Contributor

jreback commented May 3, 2016

great! I just copied the akima exactly. It gives the same results, so might it might be right. But I'ld ideally like something better. (but don't go crazy).

@jmwoloso
Copy link
Author

jmwoloso commented May 3, 2016

Haha, sounds good. I was eyeballing akima as well. I'll see what else I can come up with. Thanks again! This was fun (my git-fu needs lots of work still). I'll browse for some other issues to tackle once I get these tests done.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Compat pandas objects compatability with Numpy or Python functions Missing-data np.nan, pd.NaT, pd.NA, dropna, isnull, interpolate
Projects
None yet
Development

Successfully merging this pull request may close these issues.

COMPAT: 0.18.0 scipy dev changes causing interpolation failures
3 participants