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

如何用类似rolling().corr()的方式计算DataFrame的成对差值?

计算DataFrame的成对差值(匹配滚动相关性的输出格式)

先明确你的核心需求:想要得到和rolling(3).corr()完全一致的**多层索引(time + fsym)**格式的列间成对差值结果,对吧?

先还原你的原始DataFrame方便演示:

import pandas as pd

# 构造示例数据
data = {
    'EOS': [-0.051903, 0.026936, -0.034843, -0.108108, -0.048583],
    'BTC': [-0.069088, 0.044739, -0.012935, -0.070375, 0.019509],
    'BNB': [-0.058162, 0.040303, -0.005900, -0.028180, 0.131986]
}
pt = pd.DataFrame(data, index=pd.to_datetime(['2018-11-30', '2018-12-01', '2018-12-02', '2018-12-03', '2018-12-04'], utc=True))

方法1:高效广播法(推荐)

利用pandas的数组广播特性,可以快速生成符合要求的结果,代码简洁且性能优秀:

import pandas as pd

# 获取列名列表
cols = pt.columns.tolist()
# 通过广播计算所有列间差值:(时间数, 列数) → (时间数, 列数, 列数)
diff_array = pt.values[:, :, None] - pt.values[:, None, :]
# 构造和corr输出一致的多层索引
multi_idx = pd.MultiIndex.from_product([pt.index, cols], names=['time', 'fsym'])
# 转换为目标格式的DataFrame
pair_diff = pd.DataFrame(diff_array.reshape(-1, len(cols)), index=multi_idx, columns=cols)

运行后得到的结果结构和rolling(3).corr()完全对齐:

sym          EOS       BTC       BNB
time                fsym               
2018-11-30 00:00:00+00:00  EOS  0.000000  0.017185  0.006259
                            BTC -0.017185  0.000000 -0.010926
                            BNB -0.006259  0.010926  0.000000
2018-12-01 00:00:00+00:00  EOS  0.000000 -0.017803 -0.013367
                            BTC  0.017803  0.000000  0.004436
                            BNB  0.013367 -0.004436  0.000000
...

方法2:手动遍历构造(更直观)

如果你想更清晰地理解每一步的逻辑,可以用遍历的方式实现:

import pandas as pd
import itertools

cols = pt.columns.tolist()
# 生成所有列的两两组合
all_pairs = list(itertools.product(cols, cols))
result_frames = []

for date in pt.index:
    # 取出当前时间点的所有数据
    current_row = pt.loc[date]
    # 计算每一对的差值
    pair_values = {pair: current_row[pair[0]] - current_row[pair[1]] for pair in all_pairs}
    # 转换为临时DataFrame并调整索引
    temp_df = pd.DataFrame(pair_values.values(), index=all_pairs, columns=[date]).T
    result_frames.append(temp_df)

# 合并所有结果并调整索引层级
pair_diff = pd.concat(result_frames)
pair_diff = pair_diff.stack().unstack(0).T.swaplevel().sort_index()

补充说明

你提到的“窗口大小为1的rolling窗口”理解完全正确——因为列间差值是基于单个时间点的计算,不需要跨时间窗口的聚合,只需要把每个时间点的列间差值整理成和corr()一致的多层索引格式即可。


内容的提问来源于stack exchange,提问作者Incompetent Perfectionist

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.14 08:48:29