You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

在Pandas中使用扩展窗口计算PCA,附市场数据DataFrame示例

在Pandas中基于扩展窗口计算PCA的实现方法

首先,先明确你的需求:基于包含DP、PE、BM、CAPE这些因子的时间序列DataFrame,用扩展窗口(也就是从数据起始点到当前每个时间点的累积窗口)来计算PCA,得到每个时间点对应的主成分得分。下面我给你一步步拆解实现过程:

1. 数据预处理

首先要确保你的数据格式正确,日期列是索引且为datetime类型,同时处理缺失值:

import pandas as pd
import numpy as np
from sklearn.decomposition import PCA
from sklearn.preprocessing import StandardScaler

# 假设你的数据已经读入为df
# 格式化日期索引
df['date'] = pd.to_datetime(df['date'])
df.set_index('date', inplace=True)
# 删除含缺失值的行(也可以根据需求用填充法)
df = df.dropna()

2. 定义扩展窗口的PCA计算函数

因为PCA对变量尺度敏感,所以每次计算前必须先标准化数据,然后拟合PCA模型,最后返回当前窗口最后一个样本的主成分得分(也就是当前时间点的得分):

def compute_expanding_pca(window_data, n_components=2):
    # 标准化特征:均值为0,方差为1
    scaler = StandardScaler()
    scaled_features = scaler.fit_transform(window_data)
    
    # 拟合PCA模型
    pca = PCA(n_components=n_components)
    pca.fit(scaled_features)
    
    # 返回当前窗口最后一个样本的主成分得分
    return pca.transform(scaled_features)[-1]

3. 应用扩展窗口计算

使用Pandas的expanding()方法来创建扩展窗口,然后应用我们定义的函数:

# 选择要用于PCA的特征列
feature_cols = ['DP', 'PE', 'BM', 'CAPE']
features = df[feature_cols]

# 应用扩展窗口计算PCA得分,min_periods设置为特征数+1保证模型稳定
pca_scores = features.expanding(min_periods=len(feature_cols)+1).apply(
    compute_expanding_pca,
    n_components=2,
    raw=False  # 确保传入的是DataFrame而非numpy数组
)

# 给主成分得分列命名
pca_scores.columns = ['PC1', 'PC2']

# 合并回原DataFrame
df_with_pca = pd.concat([df, pca_scores], axis=1)

4. 可选:循环实现(更高效灵活)

如果你的数据集很大,expanding().apply()可能会比较慢,这时可以用循环来实现,灵活性更高:

n_components = 2
pc_scores = []

for idx in range(len(features)):
    # 取从起始到当前行的所有数据作为扩展窗口
    current_window = features.iloc[:idx+1]
    
    # 样本数不足特征数时,填充NaN
    if len(current_window) < len(feature_cols):
        pc_scores.append([np.nan]*n_components)
        continue
    
    # 标准化+PCA拟合
    scaler = StandardScaler()
    scaled = scaler.fit_transform(current_window)
    pca = PCA(n_components=n_components)
    pca.fit(scaled)
    
    # 记录当前行的主成分得分
    current_score = pca.transform(scaled)[-1]
    pc_scores.append(current_score)

# 转换为DataFrame并合并
pca_scores_loop = pd.DataFrame(pc_scores, index=features.index, columns=['PC1', 'PC2'])
df_with_pca_loop = pd.concat([df, pca_scores_loop], axis=1)

关键注意事项

  • 标准化不可省略:PCA对变量的尺度极度敏感(比如你的CAPE数值远大于DP),如果不标准化,大尺度变量会主导主成分的方向,结果毫无意义。
  • 扩展窗口的模型特性:每次计算的PCA模型都是基于累积到当前点的所有数据拟合的,所以不同时间点的主成分载荷可能会变化,这是扩展窗口PCA的正常现象——模型会随着数据积累不断更新。
  • min_periods的设置:至少需要和特征数相同的样本数才能计算PCA,设置为len(feature_cols)+1是为了让模型更稳定,避免样本过少导致的奇异矩阵问题。

内容的提问来源于stack exchange,提问作者Évariste Galois

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.21 08:30:08