如何将Yahoo Finance多股票数据逆透视为指定长表格式?
解决方案:将Yahoo Finance宽表转换为长表格式
你遇到的问题根源是yfinance.download()返回的DataFrame采用多层列索引(MultiIndex):第一层是行情指标(Close、High等),第二层是股票代码(AAPL、WMT)。直接用melt无法处理这种结构,需要先对列索引做层级转换。
推荐方法:使用stack()快速转换
stack()可以直接将列的某一层级转为行索引,是处理这种多层列结构最简洁的方式:
import yfinance as yf import pandas as pd from datetime import date today = date.today() # 下载原始宽表数据 data = yf.download("AAPL WMT", start="2023-05-01", end=today).round(2) # 1. 将日期从索引转为普通列 data_long = data.reset_index() # 2. 将股票代码(列索引的第二层)转为行数据,生成临时索引 data_long = data_long.stack(level=1).reset_index() # 3. 重命名列名,匹配需求字段 data_long.columns = ['Date', 'Ticker', 'Adj Close', 'Close', 'High', 'Low', 'Open', 'Volume'] # 4. 调整列的顺序为要求的格式 data_long = data_long[['Date', 'Ticker', 'Close', 'High', 'Low', 'Open', 'Volume', 'Adj Close']] # 验证结果 print(data_long.head())
关键步骤说明
reset_index():把默认的日期索引转为名为Date的普通列,确保日期信息保留在列中。stack(level=1):指定将列索引的第二层(股票代码)“堆叠”为行的一部分,此时DataFrame的索引会变为Date+Ticker的组合。reset_index():把组合索引重新转为普通列,得到包含Date、Ticker和所有行情指标的长表。- 列名重命名与顺序调整:最终匹配你需要的字段顺序。
备选方法:使用melt实现(适用于复杂场景)
如果一定要用melt,可以先将多层列索引合并为单层列名,再拆分转换:
data_flat = data.reset_index() # 合并多层列名为"指标_股票代码"格式 data_flat.columns = ['_'.join(col).strip() if col[0] != 'Date' else col[0] for col in data_flat.columns] # 转换为长表,拆分指标和股票代码 data_long = pd.melt(data_flat, id_vars=['Date'], var_name='Metric_Ticker', value_name='Value') data_long[['Metric', 'Ticker']] = data_long['Metric_Ticker'].str.split('_', expand=True) # 透视回宽表结构,再调整列顺序 data_long = data_long.pivot_table(index=['Date', 'Ticker'], columns='Metric', values='Value').reset_index() data_long = data_long[['Date', 'Ticker', 'Close', 'High', 'Low', 'Open', 'Volume', 'Adj Close']]
两种方法最终都会生成你需要的长表:每一行对应单只股票的单日数据,包含Date、Ticker、Close、High、Low、Open、Volume、Adj Close字段。
内容的提问来源于stack exchange,提问作者Stix
相关产品推荐
相关产品推荐

