按股票代码匹配条件向pandas DataFrame追加行时新表为空
问题根因
- pandas
append方法的非就地特性:这是导致结果为空的核心原因。DataFrame.append()不会修改调用该方法的原DataFrame对象,只会返回拼接后的新DataFrame。原代码调用append后没有将返回值赋值回publications变量,所有拼接的结果都被直接丢弃,最后剩下的还是初始化时那个仅含列名的空DataFrame。 - 版本兼容隐患:pandas 2.0及以上版本已经完全移除了
DataFrame.append()方法,即使修正了赋值逻辑,使用高版本pandas执行原代码也会直接抛出属性错误。 - 健壮性缺陷:原循环如果遇到title字段为空值的情况,直接调用
.lower()会触发类型错误,提前中断运行。 - 性能问题:原代码采用双层嵌套循环逐行判断匹配,没有利用pandas的向量化运算能力,数据量稍大就会运行缓慢。
解决方案
优先使用pandas原生的向量化匹配 + concat拼接的方案,既解决bug也兼顾性能、版本兼容性与代码健壮性:
tickers = ['AAPL', 'GOOG'] matched_frames = [] for ticker in tickers: # 向量化判断title列是否包含当前ticker,不区分大小写,空值直接判定为不匹配 match_mask = topics_data['title'].str.lower().str.contains(ticker.lower(), na=False) # 筛选符合条件的行 matched_rows = topics_data.loc[match_mask].copy() # 为匹配行补充对应的ticker标记 matched_rows['ticker'] = ticker matched_frames.append(matched_rows) # 合并所有匹配结果,重置行索引 publications = pd.concat(matched_frames, ignore_index=True)
如果一定要在原循环逻辑基础上做最小修正,只需补上append的返回值赋值逻辑、补上空值处理即可,但这种写法不推荐在新版pandas中使用:
# 仅作为逻辑修正示例,不推荐生产环境使用 tickers = ['AAPL', 'GOOG'] publications = pd.DataFrame(columns=['ticker','title','score','url','created']) for ticker in tickers: for i in range(0,len(topics_data['title'])): current_title = str(topics_data['title'][i]) if ticker.lower() in current_title.lower(): # 必须将append的返回值重新赋值给publications publications = publications.append( {'ticker':ticker, 'title':topics_data['title'][i], 'score':topics_data['score'][i], 'url':topics_data['url'][i], 'created':topics_data['created'][i]}, ignore_index=True )
内容的提问来源于stack exchange,提问作者Alexander Gavrailov
相关产品推荐
相关产品推荐

