为 pandas 创建自定义插值函数

2024-04-24

我目前正在尝试使用 pandas 清理和填充一些缺失的时间序列数据。插值函数工作得很好,但是它没有我的数据集所需的一些(不太广泛使用的)插值函数。几个例子是一个简单的“最后”有效数据点,它会创建类似于阶跃函数的东西,或者类似对数或几何插值的东西。

浏览文档,似乎没有办法传递自定义插值函数。这样的功能直接存在于 pandas 中吗?如果没有,是否有人做过 pandas-fu 来通过其他方式有效地应用自定义插值?


Pandas 提供的插值方法是scipy.interpolate.interp1d https://docs.scipy.org/doc/scipy/reference/generated/scipy.interpolate.interp1d.html- 不幸的是,这似乎无法以任何方式扩展。我必须做类似的事情来应用 SLERP 四元数插值(使用numpy 四元数 https://github.com/moble/quaternion),而且我成功地做到了这一点。我将在此处复制代码,希望您可以根据您的目的进行调整:

def interpolate_slerp(data):
    if data.shape[1] != 4:
        raise ValueError('Need exactly 4 values for SLERP')
    vals = data.values.copy()
    # quaternions has size Nx1 (each quaternion is a scalar value)
    quaternions = quaternion.as_quat_array(vals)
    # This is a mask of the elements that are NaN
    empty = np.any(np.isnan(vals), axis=1)
    # These are the positions of the valid values
    valid_loc = np.argwhere(~empty).squeeze(axis=-1)
    # These are the indices (e.g. time) of the valid values
    valid_index = data.index[valid_loc].values
    # These are the valid values
    valid_quaternions = quaternions[valid_loc]
    # Positions of the missing values
    empty_loc = np.argwhere(empty).squeeze(axis=-1)
    # Missing values before first or after last valid are discarded
    empty_loc = empty_loc[(empty_loc > valid_loc.min()) & (empty_loc < valid_loc.max())]
    # Index value for missing values
    empty_index = data.index[empty_loc].values
    # Important bit! This tells you the which valid values must be used as interpolation ends for each missing value
    interp_loc_end = np.searchsorted(valid_loc, empty_loc)
    interp_loc_start = interp_loc_end - 1
    # These are the actual values of the interpolation ends
    interp_q_start = valid_quaternions[interp_loc_start]
    interp_q_end = valid_quaternions[interp_loc_end]
    # And these are the indices (e.g. time) of the interpolation ends
    interp_t_start = valid_index[interp_loc_start]
    interp_t_end = valid_index[interp_loc_end]
    # This performs the actual interpolation
    # For each missing value, you have:
    #   * Initial interpolation value
    #   * Final interpolation value
    #   * Initial interpolation index
    #   * Final interpolation index
    #   * Missing value index
    interpolated = quaternion.slerp(interp_q_start, interp_q_end, interp_t_start, interp_t_end, empty_index)
    # This puts the interpolated values into place
    data = data.copy()
    data.iloc[empty_loc] = quaternion.as_float_array(interpolated)
    return data

诀窍在于np.searchsorted,它很快就能找到每个值的正确插值终点。该方法的局限性在于:

  • 您的插值函数必须有效somewhat like quaternion.slerp(这不应该奇怪,因为它有常规的 ufunc 广播行为)。
  • 它仅适用于每一端仅需要一个值的插值方法,因此如果您想要例如像三次插值这样的东西(你不需要,因为已经提供了),这是行不通的。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

为 pandas 创建自定义插值函数 的相关文章

随机推荐