gpt4 book ai didi

r - `ddply`(或类似的)可以做一个滑动窗口吗?

转载 作者:行者123 更新时间:2023-12-03 20:52:51 25 4
gpt4 key购买 nike

就像是

sliding = function(df, n, f)
ldply(1:(nrow(df) - n + 1), function(k)
f(df[k:(k + n - 1), ])
)

那会像
> df
n a
1 1 0.8021891
2 2 0.9446330
...

> sliding(df, 2, function(df) with(df,
+ data.frame(n = n[1], a = a[1], b = sum(n - a))
+ ))
n a b
1 1 0.8021891 1.253178
...

除直内 ddply ,这样我就可以得到很好的语法糖
随附吗?

最佳答案

由于没有针对此问题发布答案,我想我会提出一个来证明实际上有一种更好的方法可以解决此类问题 - 也可能是 快数千倍 . (如果这没有帮助,请告诉我,但我认为这里有总比没有好)

每当我听到“移动平均线”或“滑动窗口”时, FFT卷积立即出现在我的脑海中。这是因为它可以在 中处理这些类型的问题。极其高效 方式。由于所有“滑动”都是在幕后完成的,我认为它也具有您可能要求的所有句法美。

(以下代码位于 https://gist.github.com/1320175 的一个文件中)

我们首先模拟一些数据(为了简单起见,我在这里使用整数,但当然你不需要)。

require(plyr)
set.seed(12345)

n = 10
n.sum = 2
a = sample.int(10, n, replace=T)

df = data.frame(n=1:n, a)

> df
n a
1 1 8
2 2 9
3 3 8
4 4 9
5 5 5
6 6 2
7 7 4
8 8 6
9 9 8
10 10 10

现在,我们将预先计算 n-a一口气完成。
n.minus.a = with(df, n - a)

接下来,定义一个 内核 k当与我们的输入 n.minus.a 进行卷积时,将对我们的数据进行求和(或平均/平滑/其他)。
k = rep(0, n)
k[1:n.sum] = 1

设置好所有内容后,我们可以定义一个函数来通过 fft() 在频域中有效地进行卷积。 .
myConv <- function(x, k){
Fx = fft(x)
Fk = fft(k)
Fxk = Fx * Fk
xk = fft(Fxk, inverse=T)
(Re(xk) / n)[-(1:(n.sum-1))]
}

执行它的语法很好而且很简单:

> myConv(n.minus.a, k)
[1] -14 -12 -10 -5 4 7 5 3 1

当您使用 convolve() 时,所有这些也会发生在幕后。 R中的便利函数。

> convolve(n.minus.a, k)[1:(length(n.minus.a)-n.sum+1)]
[1] -14 -12 -10 -5 4 7 5 3 1

我们现在将其与手动方法进行比较,以表明结果都是等效的:

> sliding(df, 2, function(df) with(df, data.frame(n = n[1], a = a[1], b = sum(n - a))))
n a b
1 1 8 -14
2 2 9 -12
3 3 8 -10
4 4 9 -5
5 5 5 4
6 6 2 7
7 7 4 5
8 8 6 3
9 9 8 1

最后,我们将制作 n=10^4并测试所有这些方法的速度:

> system.time(myConv(n.minus.a, k))
user system elapsed
0.002 0.000 0.002
> system.time(convolve(n.minus.a, k, type='circ')[1:(length(n.minus.a)-n.sum+1)])
user system elapsed
0.002 0.000 0.002
> system.time(sliding(df, 2, function(df) with(df, data.frame(n = n[1], a = a[1], b = sum(n - a)))))
user system elapsed
7.944 0.018 7.962

FFT 方法几乎立即返回,即使在这种粗略的时间安排下,也比手动方法快近 4000 倍。

当然,并不是每一种滑动问题都可以归入这个范式,但对于像这样的数值问题,使用 sum() (也意味着,加权平均值等)它完美地工作。无论如何,至少谷歌一下看看是否有可用的过滤器内核可以为给定的问题提供技巧,这通常是值得的。祝你好运!

关于r - `ddply`(或类似的)可以做一个滑动窗口吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7225992/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com