Python WebSocket服务中Pandas重置索引遇内存错误求助
解决Pandas DataFrame追加+reset_index导致的内存分配错误
问题根源
你当前的写法每次追加单条记录就调用reset_index(),而该方法会完整复制整个DataFrame。随着运行时间增长,DataFrame行数持续增加,每次复制的内存开销线性上升,最终触发numpy内存分配失败。同时loc[len(self._pos_data)]的单条追加方式本身效率极低,会频繁修改索引结构。
具体解决方案
方案1:批量暂存数据,减少reset_index调用频率
维护一个缓存列表,积累一定数量的记录后再批量追加到DataFrame,仅在批量操作后统一处理索引,大幅降低内存复制次数:
# 初始化时新增缓存列表和空DataFrame self._pos_buffer = [] self._pos_data = pd.DataFrame(columns=['Username', 'Symbol', 'ID', 'Date', 'TradeTime', 'Value']) # 收到新记录时先存入缓存 self._pos_buffer.append([info['Username'], info['Symbol'], int(id), _dateConvert, _timeOfTrade, _value]) # 每积累100条(可按需调整)执行批量追加 if len(self._pos_buffer) >= 100: temp_df = pd.DataFrame(self._pos_buffer, columns=self._pos_data.columns) # 用ignore_index=True自动生成连续索引,替代手动reset_index self._pos_data = pd.concat([self._pos_data, temp_df], ignore_index=True) self._pos_buffer = []
方案2:优化数据类型,降低内存占用
错误提示中数据类型为object,这类类型内存占用极高。初始化时指定更紧凑的dtype,可大幅压缩内存:
self._pos_data = pd.DataFrame( columns=['Username', 'Symbol', 'ID', 'Date', 'TradeTime', 'Value'], dtype={ 'Username': 'category', # 用户名重复率高时,用category比object省90%内存 'Symbol': 'category', # 交易品种同理 'ID': 'int32', # 根据ID数值范围选合适的整数类型,避免默认int64 'Date': 'datetime64[ns]',# 直接存datetime类型,不要存字符串 'TradeTime': 'datetime64[ns]', 'Value': 'float32' # 精度允许时,用float32替代float64 } )
方案3:单条追加场景下,替代reset_index的写法
如果业务必须单条追加,用concat+ignore_index=True直接生成连续索引,避免每次复制整个DataFrame:
new_row = pd.DataFrame( [[info['Username'], info['Symbol'], int(id), _dateConvert, _timeOfTrade, _value]], columns=self._pos_data.columns ) # ignore_index=True自动生成连续索引,无需手动reset_index self._pos_data = pd.concat([self._pos_data, new_row], ignore_index=True)
额外建议:定期清理历史数据
若业务无需保留全部历史记录,定时裁剪DataFrame大小,从根源控制内存占用:
# 仅保留最近10000条记录(可按需调整) if len(self._pos_data) > 10000: self._pos_data = self._pos_data.tail(10000).reset_index(drop=True)
内容的提问来源于stack exchange,提问作者Shrinidhi Narasimhan
相关产品推荐
相关产品推荐

