Python 熊猫可以覆盖csv,防止数据丢失

Python 熊猫可以覆盖csv,防止数据丢失,python,csv,pandas,Python,Csv,Pandas,我有一个脚本,不断更新数据帧并将其保存到磁盘(覆盖旧的csv文件)。我发现如果在保存调用时中断程序,df.to_csv(“df.csv”),所有数据都将丢失,df.csv仅包含列索引 我可能可以通过临时将数据保存到df.temp.csv,然后替换df.csv来解决问题。但是,有没有一种简单、快捷的方法使保存成为“原子”并防止数据丢失?这是我在保存调用中断时得到的堆栈跟踪 Traceback (most recent call last): File "/opt/homebrew-cask/C

我有一个脚本,不断更新数据帧并将其保存到磁盘(覆盖旧的csv文件)。我发现如果在保存调用时中断程序,
df.to_csv(“df.csv”)
,所有数据都将丢失,
df.csv
仅包含列索引

我可能可以通过临时将数据保存到
df.temp.csv
,然后替换
df.csv
来解决问题。但是,有没有一种简单、快捷的方法使保存成为“原子”并防止数据丢失?这是我在保存调用中断时得到的堆栈跟踪

Traceback (most recent call last):
  File "/opt/homebrew-cask/Caskroom/pycharm/2016.1.3/PyCharm.app/Contents/helpers/pydev/pydevd.py", line 1531, in <module>
    globals = debugger.run(setup['file'], None, None, is_module)
  File "/opt/homebrew-cask/Caskroom/pycharm/2016.1.3/PyCharm.app/Contents/helpers/pydev/pydevd.py", line 938, in run
    pydev_imports.execfile(file, globals, locals)  # execute the script
  File "/Users/user/test.py", line 49, in <module>
    d.to_csv("out.csv", index=False)
  File "/usr/local/lib/python2.7/site-packages/pandas/core/frame.py", line 1344, in to_csv
    formatter.save()
  File "/usr/local/lib/python2.7/site-packages/pandas/formats/format.py", line 1551, in save
    self._save()
  File "/usr/local/lib/python2.7/site-packages/pandas/formats/format.py", line 1652, in _save
    self._save_chunk(start_i, end_i)
  File "/usr/local/lib/python2.7/site-packages/pandas/formats/format.py", line 1666, in _save_chunk
    quoting=self.quoting)
  File "/usr/local/lib/python2.7/site-packages/pandas/core/internals.py", line 1443, in to_native_types
    return formatter.get_result_as_array()
  File "/usr/local/lib/python2.7/site-packages/pandas/formats/format.py", line 2171, in get_result_as_array
    formatted_values = format_values_with(float_format)
  File "/usr/local/lib/python2.7/site-packages/pandas/formats/format.py", line 2157, in format_values_with
    for val in values.ravel()[imask]])
  File "/usr/local/lib/python2.7/site-packages/pandas/formats/format.py", line 2108, in base_formatter
    return str(v) if notnull(v) else self.na_rep
  File "/usr/local/lib/python2.7/site-packages/pandas/core/common.py", line 250, in notnull
    res = isnull(obj)
  File "/usr/local/lib/python2.7/site-packages/pandas/core/common.py", line 73, in isnull
    def isnull(obj):
  File "_pydevd_bundle/pydevd_cython.pyx", line 937, in _pydevd_bundle.pydevd_cython.ThreadTracer.__call__ (_pydevd_bundle/pydevd_cython.c:15522)
  File "/opt/homebrew-cask/Caskroom/pycharm/2016.1.3/PyCharm.app/Contents/helpers/pydev/_pydev_bundle/pydev_is_thread_alive.py", line 14, in is_thread_alive
    def is_thread_alive(t):
KeyboardInterrupt
回溯(最近一次呼叫最后一次):
文件“/opt/homebrew-cask/Caskroom/pycharm/2016.1.3/pycharm.app/Contents/helpers/pydev/pydevd.py”,第1531行,在
globals=debugger.run(setup['file'],None,None,is_模块)
文件“/opt/homebrew-cask/Caskroom/pycharm/2016.1.3/pycharm.app/Contents/helpers/pydev/pydevd.py”,第938行,运行中
pydev_imports.execfile(文件、全局、局部)#执行脚本
文件“/Users/user/test.py”,第49行,在
d、 to_csv(“out.csv”,index=False)
文件“/usr/local/lib/python2.7/site packages/pandas/core/frame.py”,第1344行,输入到csv
格式化程序。保存()
文件“/usr/local/lib/python2.7/site packages/pandas/formats/format.py”,第1551行,保存
self._save()
文件“/usr/local/lib/python2.7/site packages/pandas/formats/format.py”,第1652行,保存
self.\u保存块(开始、结束)
文件“/usr/local/lib/python2.7/site packages/pandas/formats/format.py”,第1666行,在保存块中
引用=自我引用)
文件“/usr/local/lib/python2.7/site packages/pandas/core/internals.py”,第1443行,以to_原生类型
返回格式化程序。获取\u结果\u作为\u数组()
文件“/usr/local/lib/python2.7/site packages/pandas/formats/format.py”,第2171行,在get_result_as_数组中
格式化的值=格式化的值(浮点格式)
文件“/usr/local/lib/python2.7/site packages/pandas/formats/format.py”,第2157行,格式为
用于values.ravel()[imask]]中的val)
base_格式化程序中的文件“/usr/local/lib/python2.7/site packages/pandas/formats/format.py”,第2108行
返回str(v)if notnull(v)else self.na_rep
文件“/usr/local/lib/python2.7/site packages/pandas/core/common.py”,第250行,非空
res=isnull(obj)
文件“/usr/local/lib/python2.7/site packages/pandas/core/common.py”,第73行,在isnull中
def isnull(obj):
文件“_pydevd_bundle/pydevd_cython.pyx”,第937行,位于_pydevd_bundle.pydevd_cython.ThreadTracer._调用(_pydevd_bundle/pydevd_cython.c:15522)
文件“/opt/homebrew cask/Caskroom/pycharm/2016.1.3/pycharm.app/Contents/helpers/pydev/_-pydev\u bundle/pydev\u-is\u-thread\u-alive.py”,第14行,is\u-thread\u-alive
def线程是否处于活动状态(t):
键盘中断

您所能做的最好的事情就是实现一个信号处理程序(模块),它会终止程序,直到最后一次写入操作完成

大致如下(伪代码):


您所能做的最好的事情是实现一个信号处理程序(模块),它将终止程序,直到最后一次写入操作完成

大致如下(伪代码):


您可以创建上下文管理器来处理原子覆盖:

import os
import contextlib

@contextlib.contextmanager
def atomic_overwrite(filename):
    temp = filename + '~'
    with open(temp, "w") as f:
        yield f
    os.rename(temp, filename) # this will only happen if no exception was raised
数据帧上的
to_csv
方法将接受文件对象而不是路径,因此您可以使用:

with atomic_overwrite("df.csv") as f:
    df.to_csv(f)

我选择的临时文件名是请求的文件名,末尾有一个平铺。当然,如果您愿意,您可以更改代码以使用其他内容。我也不确定文件应该以什么模式打开,您可能需要
“wb”
,而不仅仅是
“w”

您可以创建一个上下文管理器来处理原子覆盖:

import os
import contextlib

@contextlib.contextmanager
def atomic_overwrite(filename):
    temp = filename + '~'
    with open(temp, "w") as f:
        yield f
    os.rename(temp, filename) # this will only happen if no exception was raised
数据帧上的
to_csv
方法将接受文件对象而不是路径,因此您可以使用:

with atomic_overwrite("df.csv") as f:
    df.to_csv(f)

我选择的临时文件名是请求的文件名,末尾有一个平铺。当然,如果您愿意,您可以更改代码以使用其他内容。我也不确定文件应该以什么模式打开,您可能需要
“wb”
,而不仅仅是
“w”

也许您可以尝试将结果附加到旧的模式,比如-
d.to_csv(“out.csv”,index=False,mode='a')
。这将防止它们被覆盖。然后数据将被复制。。。如果我在储蓄电话时打断了它会发生什么?也许没有损失,但我认为也会有问题……也许你可以尝试将结果附加到旧的结果,比如-
d.to_csv(“out.csv”,index=False,mode='a')
。这将防止它们被覆盖。然后数据将被复制。。。如果我在储蓄电话时打断了它会发生什么?也许没有损失,但我想也会有问题。。。