如何基于原Pandas多层索引DataFrame创建新的多层索引DataFrame
解决多层索引DataFrame计算与赋值的报错问题
报错原因分析
你遇到的ValueError是因为尝试将多列数据(对应多家公司)直接赋值给单层列名Pct,但目标DataFrame是多层列索引结构,层级不匹配导致赋值失败。正确的做法是让每个计算结果都保持多层列索引,再合并到目标DataFrame中。
实现步骤与代码
假设你的df1列结构如下(第一层为指标,第二层为公司代码):
Adj Close High Volume AAPL MSFT AAPL MSFT AAPL MSFT Date 2023-01-03 125.07 240.08 126.89 242.23 112117500 25740000 2023-01-04 126.36 240.31 128.65 242.78 89113600 22622500 ...
以下是完整的正确实现代码:
- 计算涨跌幅(Pct Change)
从Adj Close列计算每日涨跌幅,将结果的第一层列名设为Pct:
pct_change = df1['Adj Close'].pct_change().rename_axis(columns=['Pct', 'Ticker'])
- 计算价格均线(10MA、20MA)
基于Adj Close计算不同周期的滚动均值,分别设置第一层列名:
ma10 = df1['Adj Close'].rolling(window=10).mean().rename_axis(columns=['10MA', 'Ticker']) ma20 = df1['Adj Close'].rolling(window=20).mean().rename_axis(columns=['20MA', 'Ticker'])
- 计算成交量均线(V10MA、V20MA)
基于Volume列计算滚动均值,设置对应的第一层列名:
v_ma10 = df1['Volume'].rolling(window=10).mean().rename_axis(columns=['V10MA', 'Ticker']) v_ma20 = df1['Volume'].rolling(window=20).mean().rename_axis(columns=['V20MA', 'Ticker'])
- 计算当日High高于昨日Adj Close的布尔值
将当日High与前一日Adj Close对比,得到布尔结果,第一层列名设为High_Above_Prev_Close:
high_above_prev = (df1['High'] > df1['Adj Close'].shift(1)).rename_axis(columns=['High_Above_Prev_Close', 'Ticker'])
- 合并所有结果到df2
使用pd.concat将所有计算结果按列合并,保持多层列索引结构:
import pandas as pd df2 = pd.concat([pct_change, ma10, ma20, v_ma10, v_ma20, high_above_prev], axis=1)
验证结果
最终df2的列结构会是:
Pct 10MA 20MA V10MA V20MA High_Above_Prev_Close AAPL MSFT AAPL MSFT AAPL MSFT AAPL MSFT AAPL MSFT Date 2023-01-03 NaN NaN NaN NaN NaN NaN NaN NaN True True 2023-01-04 0.0103 0.0009 NaN NaN NaN NaN NaN NaN True True ...
内容的提问来源于stack exchange,提问作者AndysPythonStuff
相关产品推荐
相关产品推荐

