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

无法重新获取的Pickle文件打开报错UnpicklingError: pickle data was truncated求助

修复截断的Pickle文件以恢复部分DataFrame数据

问题背景

服务器上通过Pandas的to_pickle()方法备份了DataFrame对象,通过VSCode迁移到本地后,文件出现截断,打开时触发UnpicklingError: pickle data was truncated错误,且服务器已关闭无法重新生成或备份数据,需要尝试恢复部分数据。

原备份代码:

import pandas as pd
congestion.to_pickle('/home/tugba/Emissions_Research/DATA2/congestion_sensitivity_short.pkl')

已尝试但失败的加载方式:

import pickle
congestion = '/Users/aysetugbaozturk/Desktop/tugba/Emissions_Research/DATA2/congestion_sensitivity.pkl'
with open(congestion, 'rb') as f:
    corpus = pickle.load(f)

data_arr = pickle.loads(congestion)
print(data_arr)

congestion = pd.read_pickle('/Users/aysetugbaozturk/Desktop/tugba/Emissions_Research/DATA2/congestion_sensitivity.pkl')

可行恢复方法

方法1:增量读取捕获可用数据片段

Pickle是流式序列化格式,截断位置前的数据可能仍可读取。通过循环加载直到报错,提取未损坏的部分:

import pickle
import pandas as pd

file_path = '/Users/aysetugbaozturk/Desktop/tugba/Emissions_Research/DATA2/congestion_sensitivity.pkl'

try:
    # 先尝试完整加载
    with open(file_path, 'rb') as f:
        df = pickle.load(f)
    print("成功加载完整DataFrame")
except pickle.UnpicklingError:
    # 增量读取,收集可用数据
    with open(file_path, 'rb') as f:
        unpickler = pickle.Unpickler(f)
        recovered_items = []
        while True:
            try:
                item = unpickler.load()
                recovered_items.append(item)
            except (EOFError, pickle.UnpicklingError):
                break
        # 尝试转为DataFrame(根据pickle结构调整)
        if recovered_items:
            try:
                df_recovered = pd.DataFrame(recovered_items[0])
                print(f"恢复部分数据,共{len(df_recovered)}行")
                print(df_recovered.head())
            except Exception as e:
                print(f"恢复原始数据片段:{recovered_items}")

方法2:用pickletools分析并截断文件到完整位置

利用pickletools解析pickle指令流,找到最后一个完整的指令位置,截断文件后尝试加载:

import pickletools
import pickle
import pandas as pd

file_path = '/Users/aysetugbaozturk/Desktop/tugba/Emissions_Research/DATA2/congestion_sensitivity.pkl'

# 第一步:解析pickle指令,找到完整数据的截断位置
with open(file_path, 'rb') as f:
    pickletools.dis(f)
# 观察输出,找到最后一个完整的指令(比如最后一个STOP标记前的位置),记录字节数truncate_at

# 第二步:截断文件到完整位置(示例值需替换为实际找到的字节数)
truncate_at = 102400  # 替换为实际解析得到的完整位置
with open(file_path, 'rb+') as f:
    f.truncate(truncate_at)

# 第三步:尝试加载修复后的文件
try:
    df = pd.read_pickle(file_path)
    print("修复后成功加载数据")
except Exception as e:
    print(f"修复后加载失败:{e}")

方法3:指定不同Pickle协议版本加载

不同Python版本的Pickle协议可能存在兼容问题,尝试指定协议版本加载:

import pickle
import pandas as pd

file_path = '/Users/aysetugbaozturk/Desktop/tugba/Emissions_Research/DATA2/congestion_sensitivity.pkl'

with open(file_path, 'rb') as f:
    # 尝试所有可用协议版本(0到5)
    for protocol in range(6):
        try:
            f.seek(0)
            df = pickle.load(f, fix_imports=True, encoding='utf-8', errors='replace', protocol=protocol)
            print(f"使用协议{protocol}成功加载数据")
            break
        except Exception as e:
            print(f"协议{protocol}加载失败:{e}")

注意事项

  • 以上方法无法保证恢复全部数据,但大概率能提取部分可用内容
  • 若恢复的是DataFrame片段,可能需要手动调整结构以正常使用
  • 后续迁移文件时建议校验文件哈希值(如MD5),确认传输完整性

内容的提问来源于stack exchange,提问作者Ayse Tugba Ozturk

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.25 11:54:06