@權倉 找到原因了,优化了一下
# 性能优化说明
# 优化点:
# prepare_data函数中的历史数据处理部分(原代码第70-80行)
# 优化内容:
# 数据获取结构优化:
# 原方案:循环中逐个股票筛选DataFrame(prices[prices['code'] == stock])
# 新方案:使用groupby('code')一次性分组,直接获取每个股票的历史数据
# 向量化处理:
# 原方案:每次循环处理单个股票(476,283次循环)
# 新方案:利用Pandas的groupby机制批量处理,减少循环次数
# 数据切片优化:
# 添加[-14:]明确取最后14个数据点,避免全量数据操作
# 预期效果:
# 时间消耗降低:
# 原耗时:3066秒(约51分钟)
# 预期耗时:约300-500秒(5-8分钟),提升6-10倍
# 内存使用优化:
# 减少重复创建DataFrame对象
# """
def prepare_data(context):
"""优化后的数据准备函数(每日14:50执行)"""
# 1. 获取所有股票并初步过滤
all_stocks = get_all_securities(['stock']).index.tolist() # 获取全市场股票列表
# 2. 批量获取当前数据(包括停牌、涨跌状态等)
current_data = get_current_data()
g.current_data_cache = current_data # 缓存当前数据
# 3. 初步过滤条件:排除创业板、科创板、ST股、停牌股
g.stock_pool = [
s for s in all_stocks
if (not (s.startswith(('300','301','688','8'))) and # 过滤创业板、科创板
not ('ST' in current_data[s].name) and # 排除ST股
not current_data[s].paused) # 排除停牌股
]
# 4. 批量获取历史价格数据(性能优化点)
if g.stock_pool:
# 获取面板数据并转换为长格式DataFrame
prices = get_price(g.stock_pool, end_date=context.current_dt,
frequency='1d', fields=['open','close','high','low','volume'],
skip_paused=True, count=14, panel=False) # 获取最近14日数据
# 使用分组优化处理(核心优化点)
g.hist_data = {} # 初始化历史数据字典
if not prices.empty:
# 按股票代码分组,一次性处理所有股票
grouped = prices.groupby('code')
for stock, group in grouped:
if len(group) >= 14:
# 直接使用分组后的数据,存储为numpy数组提升性能
g.hist_data[stock] = {
'open': group['open'].values[-14:], # 取最后14个数据点
'close': group['close'].values[-14:],
'high': group['high'].values[-14:],
'low': group['low'].values[-14:],
'volume': group['volume'].values[-14:],
'finance_41': g.finance_cache.get(stock, 0) # 使用缓存的财务数据
}
# 5. 批量获取财务数据(保持原逻辑)
q = query(
valuation.code,
valuation.market_cap # 获取市值数据
).filter(
valuation.code.in_(g.stock_pool)
)
# 获取前一日财务数据避免未来函数
fund = get_fundamentals(q, date=context.current_dt.date() - timedelta(days=1))
g.finance_cache = dict(zip(fund['code'], fund['market_cap'])) if not fund.empty else {}
2025-04-28