You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何让两个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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.14 21:07:10