سؤال

إنني أتطلع إلى العثور على ما يعادل Python لبيان Matlab التالي:

vq interp1(x,y, xq,'nearest','extrap')

يبدو وكأنه interp(xq, x, y) يعمل بشكل مثالي من أجل الاستيفاء/الاستقراء الخطي.

نظرت أيضا إلى

F = scipy.interpolate.interp1d(x, y, kind='nearest')

والذي يعمل بشكل مثالي مع الطريقة الأقرب، لكنه لن يؤدي إلى إجراء استقراء.

هل هناك أي شيء آخر أغفلته؟شكرًا.

هل كانت مفيدة؟

المحلول

بالنسبة للاستكمال الخطي الذي سيتم استقراءه باستخدام أقرب استيفاء، استخدم numpy.interp.يفعل هذا بشكل افتراضي.

على سبيل المثال:

yi = np.interp(xi, x, y)

بخلاف ذلك، إذا كنت تريد أقرب استيفاء في كل مكان، كما تصف، فيمكنك القيام بذلك بطريقة قصيرة، ولكن غير فعالة:(يمكنك جعل هذا سطرًا واحدًا، إذا أردت)

def nearest_interp(xi, x, y):
    idx = np.abs(x - xi[:,None])
    return y[idx.argmin(axis=1)]

أو بطريقة أكثر كفاءة باستخدام searchsorted:

def fast_nearest_interp(xi, x, y):
    """Assumes that x is monotonically increasing!!."""
    # Shift x points to centers
    spacing = np.diff(x) / 2
    x = x + np.hstack([spacing, spacing[-1]])
    # Append the last point in y twice for ease of use
    y = np.hstack([y, y[-1]])
    return y[np.searchsorted(x, xi)]

لتوضيح الفرق بين numpy.interp وأقرب أمثلة الاستيفاء أعلاه:

import numpy as np
import matplotlib.pyplot as plt

def main():
    x = np.array([0.1, 0.3, 1.9])
    y = np.array([4, -9, 1])
    xi = np.linspace(-1, 3, 200)

    fig, axes = plt.subplots(nrows=2, sharex=True, sharey=True)
    for ax in axes:
        ax.margins(0.05)
        ax.plot(x, y, 'ro')

    axes[0].plot(xi, np.interp(xi, x, y), color='blue')
    axes[1].plot(xi, nearest_interp(xi, x, y), color='green')

    kwargs = dict(x=0.95, y=0.9, ha='right', va='top')
    axes[0].set_title("Numpy's $interp$ function", **kwargs)
    axes[1].set_title('Nearest Interpolation', **kwargs)

    plt.show()

def nearest_interp(xi, x, y):
    idx = np.abs(x - xi[:,None])
    return y[idx.argmin(axis=1)]

main()

enter image description here

نصائح أخرى

في الإصدارات الأحدث من SciPy (على الأقل الإصدار 0.19.1+)، scipy.interpolate.interp1d لديه الخيار fill_value = “extrapolate”.

على سبيل المثال:

import pandas as pd
>>> s = pd.Series([1, 2, 3])
Out[1]: 
0    1
1    2
2    3
dtype: int64

>>> t = pd.concat([s, pd.Series(index=s.index + 0.1)]).sort_index()
Out[2]: 
0.0    1.0
0.1    NaN
1.0    2.0
1.1    NaN
2.0    3.0
2.1    NaN
dtype: float64

>>> t.interpolate(method='nearest')
Out[3]: 
0.0    1.0
0.1    1.0
1.0    2.0
1.1    2.0
2.0    3.0
2.1    NaN
dtype: float64

>>> t.interpolate(method='nearest', fill_value='extrapolate')
Out[4]: 
0.0    1.0
0.1    1.0
1.0    2.0
1.1    2.0
2.0    3.0
2.1    3.0
dtype: float64

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top