如何在多层索引DataFrame中使用pd.melt()并显示股票代码?
解决pd.melt后'Ativo'列不显示股票代码的问题
场景1:使用yfinance.download批量拉取数据(返回多层索引列)
当你用yfinance.download()拉取多只股票时,返回的数据列是多层索引(MultiIndex),第一层是行情指标(Open、High等),第二层是股票代码。直接用pd.melt()会丢失股票代码维度,需要先将多层索引转换为可识别的列:
方法1:用stack()转成长格式(推荐)
import yfinance as yf import pandas as pd acoes = ["PETR4.SA", "BOVA11.SA", "VALE3.SA"] # 拉取数据,group_by='ticker'确保按股票分组 dados = yf.download(acoes, start="2023-01-01", group_by='ticker') # 将股票代码从列索引转成单独的'Ativo'列 df_long = dados.stack(level=0).reset_index().rename(columns={'level_1': 'Ativo'})
这样处理后,df_long里的'Ativo'列会直接显示对应股票代码,后续如果需要用melt处理指标列,直接指定id_vars=['Date', 'Ativo']即可。
方法2:拆分列名后再melt
如果坚持用pd.melt(),可以先把多层索引的列名合并,再拆分出股票代码:
# 合并多层索引列名为"指标_股票代码"格式 dados.columns = dados.columns.map('_'.join) # 执行melt df_melted = dados.melt(var_name='Indicador_Ativo', value_name='Valor') # 拆分列名得到指标和股票代码 df_melted[['Indicador', 'Ativo']] = df_melted['Indicador_Ativo'].str.split('_', expand=True) # 删除临时列 df_melted = df_melted.drop('Indicador_Ativo', axis=1)
场景2:循环拉取单只股票数据后合并
如果是通过循环逐个拉取股票数据再合并,必须在每只股票的DataFrame中手动添加Ativo列存储股票代码,否则合并后会丢失该信息:
import yfinance as yf import pandas as pd acoes = ["PETR4.SA", "BOVA11.SA", "VALE3.SA"] dados_list = [] for acao in acoes: df = yf.Ticker(acao).history(start="2023-01-01") df['Ativo'] = acao # 关键:添加股票代码列 dados_list.append(df) # 合并所有数据 dados = pd.concat(dados_list) # 执行melt时保留'Ativo'列 df_melted = pd.melt(dados, id_vars=['Date', 'Ativo'], var_name='Indicador', value_name='Valor')
内容的提问来源于stack exchange,提问作者Hugo Carvalho
相关产品推荐
相关产品推荐

