|
3 | 3 | """
|
4 | 4 |
|
5 | 5 | import numpy as np
|
| 6 | +from distutils.version import LooseVersion |
6 | 7 |
|
7 | 8 | import pandas.core.common as com
|
8 | 9 | import pandas.algos as algos
|
@@ -85,13 +86,15 @@ def clean_interp_method(method, **kwargs):
|
85 | 86 | order = kwargs.get('order')
|
86 | 87 | valid = ['linear', 'time', 'index', 'values', 'nearest', 'zero', 'slinear',
|
87 | 88 | 'quadratic', 'cubic', 'barycentric', 'polynomial', 'krogh',
|
88 |
| - 'piecewise_polynomial', 'pchip', 'akima', 'spline'] |
| 89 | + 'piecewise_polynomial', 'pchip', 'akima', 'spline', |
| 90 | + 'from_derivatives'] |
89 | 91 | if method in ('spline', 'polynomial') and order is None:
|
90 | 92 | raise ValueError("You must specify the order of the spline or "
|
91 | 93 | "polynomial.")
|
92 | 94 | if method not in valid:
|
93 | 95 | raise ValueError("method must be one of {0}."
|
94 | 96 | "Got '{1}' instead.".format(valid, method))
|
| 97 | + |
95 | 98 | return method
|
96 | 99 |
|
97 | 100 |
|
@@ -191,7 +194,8 @@ def _interp_limit(invalid, fw_limit, bw_limit):
|
191 | 194 |
|
192 | 195 | sp_methods = ['nearest', 'zero', 'slinear', 'quadratic', 'cubic',
|
193 | 196 | 'barycentric', 'krogh', 'spline', 'polynomial',
|
194 |
| - 'piecewise_polynomial', 'pchip', 'akima'] |
| 197 | + 'from_derivatives', 'piecewise_polynomial', 'pchip', 'akima'] |
| 198 | + |
195 | 199 | if method in sp_methods:
|
196 | 200 | inds = np.asarray(xvalues)
|
197 | 201 | # hack for DatetimeIndex, #1646
|
@@ -228,7 +232,8 @@ def _interpolate_scipy_wrapper(x, y, new_x, method, fill_value=None,
|
228 | 232 | alt_methods = {
|
229 | 233 | 'barycentric': interpolate.barycentric_interpolate,
|
230 | 234 | 'krogh': interpolate.krogh_interpolate,
|
231 |
| - 'piecewise_polynomial': interpolate.piecewise_polynomial_interpolate, |
| 235 | + 'from_derivatives': _from_derivatives, |
| 236 | + 'piecewise_polynomial': _from_derivatives, |
232 | 237 | }
|
233 | 238 |
|
234 | 239 | if getattr(x, 'is_all_dates', False):
|
@@ -277,6 +282,60 @@ def _interpolate_scipy_wrapper(x, y, new_x, method, fill_value=None,
|
277 | 282 | return new_y
|
278 | 283 |
|
279 | 284 |
|
| 285 | +def _from_derivatives(xi, yi, x, order=None, der=0, extrapolate=False): |
| 286 | + """ |
| 287 | + Convenience function for interpolate.BPoly.from_derivatives |
| 288 | +
|
| 289 | + Construct a piecewise polynomial in the Bernstein basis, compatible |
| 290 | + with the specified values and derivatives at breakpoints. |
| 291 | +
|
| 292 | + Parameters |
| 293 | + ---------- |
| 294 | + xi : array_like |
| 295 | + sorted 1D array of x-coordinates |
| 296 | + yi : array_like or list of array-likes |
| 297 | + yi[i][j] is the j-th derivative known at xi[i] |
| 298 | + orders : None or int or array_like of ints. Default: None. |
| 299 | + Specifies the degree of local polynomials. If not None, some |
| 300 | + derivatives are ignored. |
| 301 | + der : int or list |
| 302 | + How many derivatives to extract; None for all potentially nonzero |
| 303 | + derivatives (that is a number equal to the number of points), or a |
| 304 | + list of derivatives to extract. This numberincludes the function |
| 305 | + value as 0th derivative. |
| 306 | + extrapolate : bool, optional |
| 307 | + Whether to extrapolate to ouf-of-bounds points based on first and last |
| 308 | + intervals, or to return NaNs. Default: True. |
| 309 | +
|
| 310 | + See Also |
| 311 | + -------- |
| 312 | + scipy.interpolate.BPoly.from_derivatives |
| 313 | +
|
| 314 | + Returns |
| 315 | + ------- |
| 316 | + y : scalar or array_like |
| 317 | + The result, of length R or length M or M by R, |
| 318 | +
|
| 319 | + """ |
| 320 | + import scipy |
| 321 | + from scipy import interpolate |
| 322 | + |
| 323 | + if LooseVersion(scipy.__version__) < '0.18.0': |
| 324 | + try: |
| 325 | + method = interpolate.piecewise_polynomial_interpolate |
| 326 | + return method(xi, yi.reshape(-1, 1), x, |
| 327 | + orders=order, der=der) |
| 328 | + except AttributeError: |
| 329 | + pass |
| 330 | + |
| 331 | + # return the method for compat with scipy version & backwards compat |
| 332 | + method = interpolate.BPoly.from_derivatives |
| 333 | + m = method(xi, yi.reshape(-1, 1), |
| 334 | + orders=order, extrapolate=extrapolate) |
| 335 | + |
| 336 | + return m(x) |
| 337 | + |
| 338 | + |
280 | 339 | def _akima_interpolate(xi, yi, x, der=0, axis=0):
|
281 | 340 | """
|
282 | 341 | Convenience function for akima interpolation.
|
|
0 commit comments