如何用Pandas分析DataFrame两列的联动性与相互影响?
分析Pandas DataFrame两列的联动性与相互影响
当然可以用Pandas结合统计方法实现你的需求,以下是几种比单纯看累计涨幅更系统的分析思路:
一、相关性分析:衡量整体联动强度
相关性系数是最直接的指标,能量化两列数据的线性或趋势同步性:
- 皮尔逊相关系数:适合衡量线性关系,取值范围[-1,1],绝对值越接近1说明线性联动越强
- 斯皮尔曼秩相关系数:适合衡量单调趋势的同步性(不管是否线性),比如两列数据同涨同跌但幅度不同的情况
实现代码:
import pandas as pd # 假设你的DataFrame名为df # 计算皮尔逊相关系数(默认方法) pearson_corr = df[['Col1', 'Col2']].corr().iloc[0, 1] # 计算斯皮尔曼秩相关系数 spearman_corr = df[['Col1', 'Col2']].corr(method='spearman').iloc[0, 1] print(f"皮尔逊相关系数: {pearson_corr:.4f}") print(f"斯皮尔曼秩相关系数: {spearman_corr:.4f}")
二、同步变动分析:聚焦每日波动的一致性
看累计涨幅只能反映长期趋势,分析每日变动的同步性更能体现短期联动:
- 每日涨跌幅的相关性
计算相对于前一日的涨跌幅,再看两者的相关性:
# 计算每日涨跌幅(跳过首日的NaN值) df['Col1_pct'] = df['Col1'].pct_change() df['Col2_pct'] = df['Col2'].pct_change() # 计算涨跌幅的相关系数 pct_corr = df[['Col1_pct', 'Col2_pct']].corr().iloc[0, 1] print(f"每日涨跌幅相关系数: {pct_corr:.4f}")
- 同向变动频率统计
统计两者同时上涨、同时下跌的天数占比,比例越高说明同步性越强:
# 标记涨跌幅方向(1=涨,-1=跌,0=平) df['Col1_dir'] = df['Col1_pct'].apply(lambda x: 1 if x > 0 else (-1 if x < 0 else 0)) df['Col2_dir'] = df['Col2_pct'].apply(lambda x: 1 if x > 0 else (-1 if x < 0 else 0)) # 统计有效交易日(排除两者都持平的情况) total_valid = len(df[(df['Col1_dir'] != 0) | (df['Col2_dir'] != 0)]) # 统计同向变动的天数 same_dir = len(df[(df['Col1_dir'] == df['Col2_dir']) & (df['Col1_dir'] != 0)]) print(f"同向变动天数占比: {same_dir / total_valid:.2%}")
三、因果关系检验:判断相互影响(可选)
如果要验证两列是否存在统计上的相互影响,可以用格兰杰因果检验(需要statsmodels库配合),注意这只是统计预测层面的因果,并非实际因果关系:
from statsmodels.tsa.stattools import grangercausalitytests # 清理缺失值 clean_data = df[['Col1', 'Col2']].dropna() # 检验Col1是否能预测Col2(即Col1是否是Col2的格兰杰原因) print("Col1 → Col2 格兰杰因果检验:") grangercausalitytests(clean_data[['Col2', 'Col1']], maxlag=3) # 检验Col2是否能预测Col1 print("\nCol2 → Col1 格兰杰因果检验:") grangercausalitytests(clean_data[['Col1', 'Col2']], maxlag=3)
如果检验结果的p值小于0.05,说明在95%置信水平下,拒绝"前者不是后者格兰杰原因"的原假设。
四、可视化辅助验证
用可视化能更直观地观察联动趋势:
import matplotlib.pyplot as plt # 标准化后绘制走势(消除量纲差异) normalized_df = (df[['Col1', 'Col2']] - df[['Col1', 'Col2']].mean()) / df[['Col1', 'Col2']].std() plt.figure(figsize=(12, 6)) plt.plot(df.index, normalized_df['Col1'], label='Col1') plt.plot(df.index, normalized_df['Col2'], label='Col2') plt.title('标准化后Col1与Col2的走势对比') plt.legend() plt.show() # 涨跌幅散点图 plt.figure(figsize=(8, 6)) plt.scatter(df['Col1_pct'], df['Col2_pct'], alpha=0.6) plt.xlabel('Col1 每日涨跌幅') plt.ylabel('Col2 每日涨跌幅') plt.title('Col1与Col2涨跌幅散点图') plt.show()
内容的提问来源于stack exchange,提问作者Sylv99
相关产品推荐
相关产品推荐

