如何在Pandas DataFrame中应用函数并生成指定结构的新DataFrame
问题解决:用Pandas合并多公司月度收益率为宽表
问题原因
直接用df.apply(..., axis=1)调用get_returns时,返回的是一个Series对象,其中每个元素是对应公司的收益率Series,而非你期望的多列DataFrame。因为apply(axis=1)会把每一行的处理结果作为单个元素存入结果Series,不会自动将子Series按列拼接。
解决方案
方法1:循环遍历+合并(直观易读)
遍历公司列表,逐个获取收益率Series,再用pd.concat按列合并,自动对齐日期索引:
import yfinance as yF import pandas as pd # 原始公司列表DataFrame df = pd.DataFrame({'ID':['1', '2'], 'Ticker': ['AIN', 'TILE'], 'Company':['Albany International', 'Interface']}) def get_returns(tic, com): df_Stock = yF.download(tickers=tic, period="max", interval="1mo", prepost=False, repair=False) # 按你原逻辑计算:开盘到最高价的月度涨幅 growth_col = f"{com} % Growth" df_Stock[growth_col] = (df_Stock['High'] - df_Stock['Open']) / df_Stock['Open'] * 100 return df_Stock[growth_col] # 收集所有公司的收益率数据 returns_data = [] for _, row in df.iterrows(): returns_series = get_returns(row['Ticker'], row['Company']) returns_data.append(returns_series) # 合并为宽表,将日期转为列 df1 = pd.concat(returns_data, axis=1).reset_index().rename(columns={'index': 'Date'})
方法2:改进apply用法(更简洁)
先用apply收集所有子Series,再提取后合并:
# 用apply获取每个公司的收益率Series returns_series = df.apply(lambda x: get_returns(x.Ticker, x.Company), axis=1) # 将子Series列表按列合并 df1 = pd.concat(returns_series.tolist(), axis=1).reset_index().rename(columns={'index': 'Date'})
可选:调整收益率计算逻辑
如果你需要的是传统月度收益率(而非开盘到最高价的涨幅),可以修改get_returns中的计算代码:
- 月度收盘价相对开盘价的涨幅:
df_Stock[growth_col] = (df_Stock['Close'] - df_Stock['Open']) / df_Stock['Open'] * 100 - 月度收益率(相对上月收盘价):
df_Stock[growth_col] = df_Stock['Close'].pct_change() * 100
内容的提问来源于stack exchange,提问作者prashanth manohar
相关产品推荐
相关产品推荐

