如何让两个Jupyter Notebook实时写入同一CSV且不互相覆盖数据
解决两个Jupyter Notebook共享写入同一CSV文件的冲突问题
核心问题原因
你之前的方法失效,是因为两个Notebook各自读取CSV后,DataFrame里只包含自己读取到的内容(未更新的部分会是None),最后写入时会全量覆盖整个文件,把对方已写入的数据冲成None。要解决这个问题,核心是避免全量覆盖,或者保证读写操作的原子性、互斥性。
可行解决方案
1. 使用文件锁实现互斥读写
通过文件锁确保同一时间只有一个Notebook能读写CSV,避免并发操作导致的覆盖问题。可以用filelock库:
- 先安装库:
pip install filelock
- 每个Notebook的写入逻辑:
import pandas as pd from filelock import FileLock csv_path = "shared_data.csv" lock_path = "shared_data.csv.lock" # 要更新的数据(示例:Notebook1更新第1行,Notebook2更新第2行) new_data = {"col1": ["updated_val1"], "col2": ["updated_val2"]} update_row_idx = 0 # 对应要更新的行索引 # 加锁后执行读写操作 with FileLock(lock_path): # 读取完整CSV df = pd.read_csv(csv_path) # 更新指定行 df.loc[update_row_idx] = new_data # 写入回CSV df.to_csv(csv_path, index=False)
2. 改用追加模式记录单条数据,后续合并结构化表格
如果不需要实时维护完整表格,每个Notebook只追加自己的单条数据到CSV,最后再统一整理成结构化表格:
- Notebook1的写入逻辑:
import pandas as pd new_data = {"col1": "val1_from_notebook1", "col2": "val2_from_notebook1"} # 追加模式写入,header只在第一次写入时添加 pd.DataFrame([new_data]).to_csv("shared_data.csv", mode="a", header=False, index=False)
- Notebook2的写入逻辑和上面一致,最后要生成完整表格时,读取后去重或处理重复行:
df = pd.read_csv("shared_data.csv", header=None, names=["col1", "col2"]) # 根据需求去重或合并,比如保留最新的每条记录 df = df.drop_duplicates(subset=["col1"], keep="last")
3. 临时文件+原子替换,避免部分写入覆盖
每个Notebook先把更新后的完整DataFrame写入临时文件,再原子替换原CSV文件,这样即使两个操作同时进行,也只会保留最后完成的完整版本:
import pandas as pd import os csv_path = "shared_data.csv" temp_path = "shared_data_temp.csv" # 读取原CSV df = pd.read_csv(csv_path) # 更新指定行数据 df.loc[1] = {"col1": "updated_val_from_notebook2", "col2": "updated_val2"} # 写入临时文件 df.to_csv(temp_path, index=False) # 原子替换原文件 os.replace(temp_path, csv_path)
这个方法的好处是,不会出现半覆盖的情况,但如果两个Notebook同时更新不同行,最后写入的版本会覆盖前一个,所以适合更新频率不高,或者能接受最后写入者优先的场景。
内容的提问来源于stack exchange,提问作者ZeDev
相关产品推荐
相关产品推荐

