【问题标题】:How to apply a 1D median filter to a 3D DataArray using xarray.apply_ufunc()如何使用 xarray.apply_ufunc() 将 1D 中值滤波器应用于 3D DataArray
【发布时间】:2019-07-18 10:31:49
【问题描述】:

我有 3 维 DataArray(使用 xarray)。我想沿某个维度对其应用一维。具体来说,我想应用 scipy.signal.medfilt() 函数,但它应该是一维的。

到目前为止,我已经通过以下方式成功实现了这一点:

for sample in data_raw.coords["sample"]:
    for experiment in data_raw.coords["experiment"]:
        data_filtered.loc[sample,experiment,:] = signal.medfilt(data_raw.loc[sample,experiment,:], 15)

(我的数据数组有维度“sample”、“experiment”和“wave_number”。此代码沿“wave_number”维度应用过滤器)

这样做的问题是计算需要相当长的时间,我的直觉告诉我,像这样循环坐标是一种低效的方法。所以我正在考虑使用xarray.apply_ufunc() 函数,特别是因为我在相同的代码中以类似的方式使用了它:

xr.apply_ufunc(np.linalg.norm, data, kwargs={"axis": 2}, input_core_dims=[["wave_number"]])

(这会计算向量沿“wave_number”维度的长度。)

我最初也有这个循环通过坐标,就像这里的第一个代码一样。

问题出在我尝试的时候

xr.apply_ufunc(signal.medfilt, data_smooth, kwargs={"kernel_size": 15})

它返回一个全零的数据数组,大概是因为它应用了 3D 中值滤波器并且数据数组包含 NaN 条目。我意识到这里的问题是我需要为scipy.signal.medfilt() 函数提供一维数组,但不幸的是,无法指定沿其应用过滤器的轴(与numpy.linalg.norm() 不同)。

那么,如何在不循环坐标的情况下应用一维中值滤波器?

【问题讨论】:

    标签: python scipy python-xarray


    【解决方案1】:

    如果我理解正确,你应该这样使用它:

    xr.apply_ufunc(signal.medfilt, data_smooth, kwargs={"kernel_size": 15}, input_core_dims = [['wave_number']], vectorize=True)
    

    使用vectorize = True,您可以将输入函数矢量化,以应用于定义为保留核心尺寸的数组切片。

    尽管如此,如documentation 所述:

    此选项的存在是为了方便,但几乎总是比提供预矢量化函数慢

    因为实现本质上是一个 for 循环。但是,我仍然比自己制作循环获得更快的结果。

    【讨论】:

      猜你喜欢
      • 2016-02-04
      • 2016-01-26
      • 2018-09-19
      • 1970-01-01
      • 2021-01-05
      • 2019-08-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多