[python技巧]使用pickle.dump出现memoryError

当使用pickle处理大量numpyarrays数据时,可能会遇到MemoryError。本文介绍了一种解决方案,即采用joblib库进行数据持久化存储。joblib不仅避免了pickle的内存限制问题,还提供了并行处理和压缩存储等功能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

问题描述:

    在使用pickle来持久化将大量的numpy arrays存入硬盘时候,使用pickle.dump方法的时出现MemoryError。

解决办法:

    本质原来是因为pickle本身的一些bug,对大量数据无法进行处理,但是在pickle4.0+可以对4G以上的数据进行操作,stack overflow上有人给出了一些解释和分批次写入disk的方法 。

    但是我觉得这都是不是一些好办法,最好的办法就是抛弃pickle,使用joblib这个包来实现持久化存储。其主页详细介绍了如何来使用joblib。

    简单介绍一下joblib中dump和load的使用,比如如果我们要将一个numpy arrays存入文件:

   

import numpy as np
data = [('a', [1, 2, 3]), ('b', np.arange(10))]
with open(filename, 'wb') as fo:  
    joblib.dump(data, fo)
with open(filename, 'rb') as fo:  
    joblib.load(fo)

    joblib还有并行处理和压缩存储等功能,这些都可以在主页找到相应的example。

 

 

   

   

   

from scapy.all import * import subprocess import datetime import pickle import config import sched, time ##正常端口 allow_ports = config.allow_ports ##白名单ip allow_ip=config.allow_ip local_ip=config.local_ip ip_map={} import threading # 定义一个线程函数 def task(): while True: need_del_map=[] for ip in ip_map: diff=datetime.datetime.now()-ip_map[ip] seconds=diff.total_seconds() if seconds >600: remove_firewall(ip) if ip in ip_map: need_del_map.append(ip) for key in need_del_map: ip_map.pop(key) with open("data.pickle", "wb") as outfile: pickle.dump(ip_map, outfile) time.sleep(5) # 创建一个新线程 t = threading.Thread(target=task) # 启动线程 t.start() if os.path.exists("data.pickle"): try: with open("data.pickle", "rb") as infile: ip_map = pickle.load(infile) except Exception: print(" load hisfile error") print(ip_map) def packet_callback(packet): if packet.haslayer(TCP): if packet[TCP].flags == 'S': try: src_ip = packet[IP].src dst_ip = packet[IP].dst if dst_ip != local_ip: return dst_port = packet[TCP].dport if not src_ip in allow_ip: if str(dst_port) in allow_ports: print("ip:"+src_ip+",allow visit port:",dst_port) return else: if src_ip in ip_map: ip_map[src_ip]=datetime.datetime.now() return add_firewall(src_ip) with open("addfilewall.log", "a") as outfile: outfile.write(str(packet)+"\n") except Exception as e: print("error",e) lock = threading.Lock() def add_firewall(ip): lock.acquire() src_ip=ip command = f"netsh advfirewall firewall show rule name=\"{src_ip}\"" output = subprocess.run(command, capture_output=True, text=True) if "没有与指定标准相匹配的规则。" in output.stdout: command = "netsh advfirewall firewall add rule name="+src_ip+" dir=in action=block remoteip="+src_ip subprocess.run(command, capture_output=True, text=True, check=False) ip_map[src_ip]=datetime.datetime.now() print("ban ip"+src_ip) else: ip_map[src_ip]=datetime.datetime.now() print(" exit rule name:"+src_ip) with open("data.pickle", "wb") as outfile: pickle.dump(ip_map, outfile) lock.release() def remove_firewall(ip): lock.acquire() command = "netsh advfirewall firewall delete rule name="+ip subprocess.run(command, capture_output=True, text=True, check=False) print("清除禁用规则:"+ip) lock.release() sniff(filter="tcp", prn=packet_callback) 是什么作用,运行久了内存会增加,请给出建议并提供修改后的代码
最新发布
07-17
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值