如何在Jupyter Notebook中实现大DataFrame跨会话保持加载状态
Jupyter Notebook跨会话持久化大体积DataFrame解决方案
方案1:二进制序列化格式快速加载(最推荐)
你之前遇到的每次导入耗时久的核心原因是csv格式读取效率低,换成二进制存储格式后,200万行数据读取耗时基本能控制在1秒内,使用体验和「保持加载状态」几乎无差异:
- 首次读取csv后将df存为feather格式,若提示缺少依赖可执行
pip install pyarrow安装:
import pandas as pd # 首次读取仅执行一次 df = pd.read_csv('myfile.csv') df.to_feather('myfile.feather')
- 后续所有会话需要调用df时,直接读取feather文件即可:
df = pd.read_feather('myfile.feather')
如果df中包含复杂自定义类型字段,可替换为parquet格式,用法完全一致,兼容性更强
方案2:共享内存持久化(完全无需重复读盘)
如果确实需要完全跳过磁盘读取环节,且设备内存足够容纳该DataFrame,可以使用Apache Arrow的Plasma共享内存存储,将数据存放在共享内存区域,跨会话可直接读取:
- 第一步先在终端启动Plasma存储服务,分配足够的内存(示例分配10G,可根据df实际大小调整):
plasma_store -m 10000000000 -s /tmp/plasma - 首次加载df后存入共享内存:
import pyarrow as pa import pyarrow.plasma as plasma client = plasma.connect("/tmp/plasma") # 自定义16字节的唯一标识ID object_id = plasma.ObjectID(b"mydfid0000000000000000") client.put(pa.Table.from_pandas(df), object_id)
- 其他会话直接读取共享内存中的df:
import pyarrow.plasma as plasma import pyarrow as pa client = plasma.connect("/tmp/plasma") object_id = plasma.ObjectID(b"mydfid0000000000000000") df = client.get(object_id).to_pandas()
只要Plasma服务不终止,共享内存中的数据就会一直保留,设备重启后需要重新存入
方案3:内核持久化(适合本地使用场景)
如果是本地运行的Jupyter服务,不需要关闭Jupyter进程的话,关闭笔记本标签页/编辑器窗口时可以选择不终止运行中的内核,下次打开同一个笔记本时,选择原有运行中的内核连接,即可直接使用内存中已经加载的df,无需任何重新加载操作。
此前方案失效原因说明
- 导入
mydata.py重复加载:Python导入模块时会执行模块内所有顶层代码,每次重启会话重新导入都会重新运行read_csv逻辑,必然会重新加载数据 %store失效:%store魔法函数的本质是将变量序列化存储到磁盘,恢复时再反序列化加载,200万行DataFrame使用默认pickle序列化不仅体积大,反序列化时内存开销极高,很容易触发内存限制报错
内容的提问来源于stack exchange,提问作者céline
相关产品推荐
相关产品推荐

