是否可以从移动平均数据中提取数据点?
换句话说,如果一组数据仅具有前30个点的简单移动平均值,是否可以提取原始数据点?
如果是这样,怎么办?
是否可以从移动平均数据中提取数据点?
换句话说,如果一组数据仅具有前30个点的简单移动平均值,是否可以提取原始数据点?
如果是这样,怎么办?
Answers:
+1是fabee的答案,这是完整的。只是根据我发现可以进行手头操作的软件包,将其转换为R的注释。就我而言,我的数据是三个月的NOAA温度预测:1月-2月-3月,2月-3月-4月,3月-4月-5月等,我想将其分解为(近似)假设每个三个月的温度基本上是一个平均值,则为月度值。
library (Matrix)
library (matrixcalc)
# Feb-Mar-Apr through Nov-Dec-Jan temperature forecasts:
qtemps <- c(46.0, 56.4, 65.8, 73.4, 77.4, 76.2, 69.5, 60.1, 49.5, 41.2)
# Thus I need a 10x12 matrix, which is a band matrix but with the first
# and last rows removed so that each row contains 3 1's, for three months.
# Yeah, the as.matrix and all is a bit obfuscated, but the results of
# band are not what svd.inverse wants.
a <- as.matrix (band (matrix (1, nrow=12, ncol=12), -1, 1)[-c(1, 12),])
ai <- svd.inverse (a)
mtemps <- t(qtemps) %*% t(ai) * 3
这对我来说很棒。谢谢@fabee。
编辑:好的,将我的R反向翻译为Python,我得到:
from numpy import *
from numpy.linalg import *
qtemps = transpose ([[46.0, 56.4, 65.8, 73.4, 77.4, 76.2, 69.5, 60.1, 49.5, 41.2]])
a = tril (ones ((12, 12)), 2) - tril (ones ((12, 12)), -1)
a = a[0:10,:]
ai = pinv (a)
mtemps = dot (ai, qtemps) * 3
(调试所需的时间比R版本要长得多。首先是因为我不像R那样熟悉Python,还因为R在交互方面更有用。)
我试着把胡言乱语的答案。假设您有一个大向量其中n = 2000个条目。如果计算的移动平均值与长度的窗口ℓ = 30,则可以写为一个向量矩阵乘法Ŷ = 甲X的向量X与矩阵
其中有个将随着您在行中的移动而移动,直到30个到达矩阵的末尾。此处,平均向量y具有1970维。矩阵有1970行和2000列。因此,它不是不可逆的。
如果你不熟悉的矩阵,想想它作为一个线性方程组:您正在搜索的变量,则前三十个平均值y 1,后二十个平均值y 2,依此类推。
方程系统(和矩阵)的问题在于,它比方程具有更多的未知数。因此,你不能唯一地识别您的未知数。直观的原因是您在求平均值时放宽了尺寸,因为x的前三十个尺寸在y中没有得到对应的元素,因为您无法将求平均值窗口移到x之外。
一种使或等价的方程组可求解的方法是,提出30个以上的方程(或A的30个行),这些方程可提供附加信息(与A的所有其他行线性独立)。
另外,也许更容易,方法是使用伪逆的一个。这将生成向量z = A † y,该向量的维数与x相同,并且具有使y和A z之间的二次距离最小的特性(请参阅Wikipedia)。
许多数值程序提供伪逆(例如Matlab,python中的numpy等)。
这是从我的示例生成信号的python代码:
from numpy import *
from numpy.linalg import *
from matplotlib.pyplot import *
# get A and its inverse
A = (tril(ones((2000,2000)),-1) - tril(ones((2000,2000)),-31))/30.
A = A[30:,:]
pA = pinv(A) #pseudo inverse
# get x
x = random.randn(2000) + 5
y = dot(A,x)
# reconstruct
x2 = dot(pA,y)
plot(x,label='original x')
plot(y,label='averaged x')
plot(x2,label='reconstructed x')
legend()
show()
希望能有所帮助。