【问题标题】:Gaussian filter with uneven sampled data具有不均匀采样数据的高斯滤波器
【发布时间】:2016-04-29 06:12:31
【问题描述】:

我有一个采样不均匀的时间序列,我想将其下采样到 20Hz。我通过在 0.05 秒时间窗口 (20Hz) 中对数据点进行分箱并对其应用算术平均值来制作移动平均值。数据框如下所示:

          Time    Right     Left
1  0.000000000 18.21980 30.98789
2  0.009222031 22.15157 37.18590
3  0.022511959 25.63218 42.49231
4  0.029854059 28.43851 46.57811
5  0.039320946 30.43885 49.29414
6  0.052499056 31.60561 50.67852
7  0.059612036 32.01045 50.92879
8  0.076606989 31.80335 50.34975
9  0.082647085 31.18134 49.29151
10 0.090698957 30.35415 48.09110

我用于移动平均线的代码是这样的:

data$group_num <- floor(data$Time/0.05)

data2<-NULL

data2$Right = aggregate(data$Right,
                               list(group_num=data$group_num), mean)
data2$Left = aggregate(data$Left,
                                     list(group_num=data$group_num), mean)
data2$Time = aggregate(data$Time,
                                 list(group_num=data$group_num), mean)

但是,为了优化它,我想制作一个高斯滤波器,以便 bin 中间的数据点具有更大的权重。我找不到任何可以处理不均匀采样的函数。因此,我开始编写脚本,并设法赋予它们权重。

data$weight <- ((data$Time-data$group_num*0.05)*((data$group_num+1)*0.05-data$Time))^5

我必须通过它们自己的 bin 中的权重的平均值来标准化这些权重(例如)。通过尝试将这些权重归一化为他们自己组的平均值,我遇到了函数太慢的问题。有谁能帮帮我吗?

【问题讨论】:

  • 我建议查看zoo 包的rollmeanrollapply 函数
  • 如果我理解正确的话,这些函数使用固定数量的数据点进行分箱。这就是我迄今为止看到的每个功能的工作方式。但是,由于我的采样不均匀,我根据时间窗口对它们进行分类,其中一些有 3 个数据点,其他 4 个或 5 个或 6 个......
  • 好的,那么data.table 是否适合您?
  • 我一直在尝试 data.table 的一些功能,但我仍然想不出一个可以帮助我的功能。我遇到的主要问题是,在找到一个权重(有不同的方法)之后,我需要一个归一化,以便我可以将该权重乘以时间、右、左。问题是为了规范化我制作了一个新表,因为长度等于 max(group_num) 而不是原始数据帧的长度。一旦到了那个时候,我就被卡住了,只是设法以一种非常低效的方式做到这一点
  • 我想到了类似data.table(data)[,group_num:=floor(Time/.05),][,weight:=((Time-group_num*0.05)*((group_num+1)*0.05-Time))^5][,list(Right=mean(Right*weight/sum(weight)),Left=mean(Left*weight/sum(weight))),group_num][]

标签: r filter gaussian


【解决方案1】:

我终于做到了我想做的事。帮助我克服这个问题的关键函数是 ave()。感谢上帝。所以这就是我基本上所做的:

data$weight <- (abs(data$Time-(data$group_num*0.05+0.025)))^(-1)

data$Norm<-ave(data$weight,data$group_num,FUN=function(x) x/sum(x))

data$Time2<- data$Time*data$Norm

data$Right2<- data$Right*data$Norm

data$Left2<- data$Left*data$Norm

data2$Time<- tapply(data$Time2, data$group_num, sum)

data2$Right<- tapply(data$Right2, data$group_num, sum)

data2$Left<- tapply(data$Left2, data$group_num, sum)

感谢 Marat Talipov 的帮助。从我在你的代码中看到的,这也可以工作。但是因为它工作得很好而且足够快,所以我会坚持下去。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-10-25
    • 1970-01-01
    • 1970-01-01
    • 2018-10-03
    • 1970-01-01
    • 2013-03-29
    • 1970-01-01
    • 2012-04-26
    相关资源
    最近更新 更多