带有常量的Python矢量化

2024-06-17 12:52:26 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个长度为n(=300000)的X系列。使用窗口长度w(=40),我需要实现:

mu(i)=X(i)-X(i-w)

s(i)=和{k=i-w到i}[X(k)-X(k-1)-mu(i)]^2

我想知道有没有办法防止循环。mu(i)在第二个方程中是常数这一事实导致了矢量化的复杂性。到目前为止,我做了以下工作:

x1=x.shift(1)
xw=x.shift(w)
mu= x-xw 
dx=(x-x1-mu)**2 # wrong because mu wouldn't be constant for each i
s=pd.rolling_sum(dx,w)

上面的代码可以在循环设置中工作(并且正在工作),但是需要的时间太长,所以任何关于矢量化或其他速度改进方法的帮助都会很有帮助。我把这个贴在了交叉验证的mathjax格式上,但在这里似乎不起作用。你知道吗

https://stats.stackexchange.com/questions/241050/python-vectorization-with-a-constant

另外,为了澄清,我没有使用双循环,只是一个单循环:

        for i in np.arange(w, len(X)):
            x=X.ix[i-w:i,0] # clip a series of size w
            x1=x.shift(1)   
            mu.ix[i]= x.ix[-1]-x.ix[0]   
            temp= (x-x1-mu.ix[i])**2   # returns a series of size w but now mu is constant
            s.ix[i]= temp.sum()

Tags: offorsizeshifttemp矢量化seriesix
1条回答
网友
1楼 · 发布于 2024-06-17 12:52:26

方法#1:一种矢量化方法将使用^{}-

N = X.shape[0]
a = np.arange(N)
k2D = a[:,None] - np.arange(w+1)[::-1]
mu1D = X - X[a-w]
out = ((X[k2D] - X[k2D-1] - mu1D[:,None])**2).sum(-1)

我们可以进一步优化最后一步,得到^{}-

subs = X[k2D] - X[k2D-1] - mu1D[:,None]
out = np.einsum('ij,ij->i',subs,subs)

通过使用^{}获得X[k2D]X[k2D-1],可以进一步改进。你知道吗


方法#2:为了在处理非常大的数组时节省内存,我们可以使用一个循环,而不是原始代码中使用的两个循环,如-

N = X.shape[0]
s = np.zeros((N))
k_idx = np.arange(-w,1)
for i in range(N):
    mu = X[i]-X[i-w]
    s[i] = ((X[k_idx]-X[k_idx-1] - mu)**2).sum()
    k_idx += 1

同样,这里可以用np.einsum来计算s[i],就像这样-

subs = X[k_idx]-X[k_idx-1] - mu
s[i] = np.einsum('i,i->',subs,subs)

相关问题 更多 >