我有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)
(我的数据数组的维度为“样本”,“实验”和“ 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()
不同)。
那么,如何在不循环浏览坐标的情况下应用一维中值滤波器?
答案 0 :(得分:0)
如果我理解正确,则应该这样使用它:
xr.apply_ufunc(signal.medfilt, data_smooth, kwargs={"kernel_size": 15}, input_core_dims = [['wave_number']], vectorize=True)
使用vectorize = True
可以向量化输入函数,以将其应用于定义为保留核心维的数组切片。
尽管如此,如documentation所述:
此选项是为了方便起见而存在的,但是它总是比提供预向量化的功能慢
因为实现本质上是一个for循环。但是,我仍然比通过自己创建循环来获得更快的结果。