在pandas数据框上进行滚动主成分分析

6
我想知道有没有人知道如何在pandas dataframe上实现滚动/移动窗口PCA。我查找了R和MATLAB的实现,但没有Python的实现。任何帮助都将不胜感激!
这不是重复问题 - 滚动窗口PCA与整个数据框的PCA不同。如果您不理解差异,请参阅pandas.DataFrame.rolling()。

3
这太宽泛了。描述一下你想要什么,以及对于在数据帧上使用简单的for循环,每个使用sklearn的pca有什么问题?你提到了其他语言中类似的工具,但没有链接或任何正式的描述。 - sascha
1
为什么你想要一个滚动PCA呢?从统计学的角度来看,这没有任何意义。 - Stergios
4
您想要滚动均值或滚动标准差的原因与这个一样。底层数据是时间序列。 - Michael
@Michael 有点晚了,但我刚在这里留下了一个答案(链接:https://dev59.com/YcX5oIgBc1ULPQZF8eag#73652616),希望对你有所帮助。 - PyRsquared
1个回答

6

不幸的是,pandas.DataFrame.rolling() 似乎会在滚动之前将 df 展平,因此不能像人们期望的那样滚动 df 的行并将行窗口传递给 PCA。

以下是一种基于索引滚动而不是行滚动的解决方法。它可能不太优雅,但却有效:

# Generate some data (1000 time points, 10 features)
data = np.random.random(size=(1000,10))
df = pd.DataFrame(data)

# Set the window size
window = 100

# Initialize an empty df of appropriate size for the output
df_pca = pd.DataFrame( np.zeros((data.shape[0] - window + 1, data.shape[1])) )

# Define PCA fit-transform function
# Note: Instead of attempting to return the result, 
#       it is written into the previously created output array.
def rolling_pca(window_data):
    pca = PCA()
    transf = pca.fit_transform(df.iloc[window_data])
    df_pca.iloc[int(window_data[0])] = transf[0,:]
    return True

# Create a df containing row indices for the workaround
df_idx = pd.DataFrame(np.arange(df.shape[0]))

# Use `rolling` to apply the PCA function
_ = df_idx.rolling(window).apply(rolling_pca)

# The results are now contained here:
print df_pca

快速检查发现,通过这种方法产生的值与手动切割适当窗口并对其进行PCA计算得出的控制值相同。


这个在运行时是否相当于手动切片并对每个切片执行独立的PCA?还是有什么东西可以让你在向前移动窗口时重复使用现有的PCA,从而节省时间? - Jacob Steinebronn
这相当于独立的PCA。尝试找到一种方法来保留现有的PCA可能会很有趣。也许scikit-learn的“IncrementalPCA”可以作为灵感来源。 - WhoIsJack
我一直在研究这个,但 IPCA 无法删除记录,因此它只是半个解决方案。 - Jacob Steinebronn
1
代码在这一行给我一个KeyError: 0 --> df_pca.iloc[int(window_data[0])] = transf[0,:]。你有什么想法为什么会出现这种情况吗? - Luigi87
尝试使用 window_data.iloc[0],因为它是一个 pd.Series。 - user3882675
窗口数据应该是什么?希望能够得到一些明确的解释。 - Draco D

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接