FUJITSU服务器下Numpy加载大矩阵慢且易挂,求优化方案
优化超大矩阵加载的解决方案
先帮你拆解下核心问题:numpy.loadtxt 是纯Python实现的文本解析工具,逐行处理文本数据的效率低得离谱;而且单个12G的矩阵已经占了你64G内存的近五分之一,加载6个的话总内存需求直接干到72G,远超系统可用内存,必然触发磁盘交换(swap),把系统资源耗干导致死机。下面给你几个针对性的优化方案:
1. 改用二进制格式存储(最优先推荐)
文本格式存储超大矩阵本身就不合理——不仅占更多磁盘空间,加载速度还慢到离谱。建议你先一次性把文本矩阵转成二进制格式(只做一次),后续加载直接用二进制:
转换文本到二进制
import numpy as np # 虽然第一次加载慢,但只需要执行一次 arr = np.loadtxt("your_matrix.txt") # 保存为二进制npy格式,体积小、加载快 np.save("matrix_01.npy", arr)
加载二进制矩阵
# 加载速度比loadtxt快几十甚至上百倍 arr = np.load("matrix_01.npy")
如果矩阵实在太大,不想一次性加载到内存,可以用内存映射(memmap),直接操作磁盘上的二进制文件,无需把整个矩阵读入内存:
# 创建内存映射数组,mode='r'表示只读 arr = np.memmap("matrix_01.npy", dtype=np.float64, mode='r', shape=(38756, 38756)) # 操作时和普通numpy数组一样,只会把需要的部分加载到内存 subset = arr[0:1000, 0:1000]
2. 优化文本加载(如果必须保留文本格式)
如果因为某些原因不能转二进制,可以用更快的文本解析工具:
- 用pandas读取后转numpy数组:pandas的
read_csv用了C优化的解析器,比numpy.loadtxt快很多:
import pandas as pd import numpy as np # 假设你的文本是空格分隔,header=None表示没有表头 df = pd.read_csv("your_matrix.txt", sep=" ", header=None) arr = df.to_numpy() # pandas 0.24+支持,旧版本用df.values
- 分块加载文本:如果一次性加载内存不够,可以分块读取后拼接:
chunk_size = 10000 chunks = [] for i in range(0, 38756, chunk_size): # 每次加载chunk_size行 chunk = np.loadtxt("your_matrix.txt", skiprows=i, maxrows=min(chunk_size, 38756-i)) chunks.append(chunk) arr = np.concatenate(chunks, axis=0)
3. 降低内存占用
6个12G的float64矩阵总需求72G,超过了你的64G内存,所以可以考虑降低数据类型:
- 如果矩阵元素不需要双精度(float64),可以转成单精度(float32),内存直接减半:
# 加载时指定dtype arr = np.loadtxt("your_matrix.txt", dtype=np.float32) # 或者转格式后保存,后续加载直接用压缩后的格式 arr = arr.astype(np.float32) np.save("matrix_01_float32.npy", arr)
这样6个矩阵总内存需求降到36G,完全在你的64G内存范围内,不会触发swap导致死机。
4. 升级Python版本(长期建议)
Python2.7已经停止维护多年,numpy等库对它的性能优化也停滞了。升级到Python3.8+,配合最新版的numpy/pandas,能获得更好的解析性能和内存管理能力,很多底层实现都做了优化,加载速度会有明显提升。
内容的提问来源于stack exchange,提问作者user30
相关产品推荐
相关产品推荐

