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

如何无循环高效拼接数组?优化大规模Numpy数组加载代码

如何精简合并大量Numpy数组的代码并提速?

首先看你原来的嵌套循环代码,在M达到百万级的时候效率肯定拉胯,numpy本身就有很多向量化的批量处理能力,完全可以摆脱循环,把速度提上去一大截。

核心优化方案

你的需求是把每个sample{i}.npy里的一维数组(长度41632)堆叠成M×41632的二维数组,最直接的无循环实现方式是批量加载所有数组后一次性合并:

import numpy as np

M = 100  # 替换成你的实际M值,最高支持到1e6
# 用列表推导式批量加载所有npy文件,这比手动写for循环快很多
loaded_arrays = [np.load(f'sample{i}.npy') for i in range(M)]
# 直接转为二维数组,numpy会自动完成堆叠操作
sample = np.array(loaded_arrays)

为什么这方法更快?

  • 列表推导式是Python底层优化过的语法,比手动写for循环+append的效率高不少
  • np.array()是基于C实现的向量化操作,完全避开了Python层面的循环,处理百万级数据的速度会比你原来的代码快几个数量级

百万级M的内存注意事项

当M达到一百万时,内存占用会非常可观:

  • 如果每个数组是float64类型,单个数组占41632*8=333056字节≈325KB,一百万个数组总内存约为316GB,这远超普通机器的内存容量
  • 这种情况下建议分块处理:每次加载一小批文件合并,把分块后的数组保存到磁盘,最后再按需合并分块,避免一次性占满内存

分块处理的示例代码:

import numpy as np

M = 1000000
block_size = 10000  # 每次处理10000个文件,可根据内存调整
num_blocks = M // block_size

for block_idx in range(num_blocks):
    start = block_idx * block_size
    end = start + block_size
    # 加载当前块的所有数组
    block_arrays = [np.load(f'sample{i}.npy') for i in range(start, end)]
    block = np.array(block_arrays)
    # 保存分块到磁盘
    np.save(f'block_{block_idx}.npy', block)
    print(f"完成块 {block_idx+1}/{num_blocks}")

# 后续需要完整数组时,再加载所有分块合并
# full_sample = np.vstack([np.load(f'block_{i}.npy') for i in range(num_blocks)])

额外小技巧

如果你的sample{i}.npy文件命名连续,还可以用glob模块批量获取文件名,避免手动生成索引:

import glob
import numpy as np

# 获取所有sample开头的npy文件,排序保证顺序正确
file_paths = sorted(glob.glob('sample*.npy'))
loaded_arrays = [np.load(path) for path in file_paths]
sample = np.array(loaded_arrays)

这样代码更简洁,也不用担心文件名索引出错的问题。

内容的提问来源于stack exchange,提问作者user23299

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.20 10:34:25