如何高效判断随机数组是否为大矩阵的列?(Python)
优化二进制数组去重填充大矩阵的高效方案
看了你的代码,核心问题在于每次判断新生成的数组是否重复时,都要遍历整个大矩阵的所有列做减法求和——这在loop_size和arr_size较大时,时间和内存开销都会爆炸。毕竟你用np.zeros默认存的是float64,光这个大矩阵的内存占用就够夸张的。这里给你几个针对性的优化思路,亲测能大幅提升速度和内存效率:
1. 用哈希集合替代全矩阵比对(最通用的优化)
原来的重复判断是O(loop_size * arr_size)的时间复杂度,我们可以把二进制数组转换成可哈希的唯一标识(比如整数),用集合来做O(1)的存在性检查,同时把大矩阵的 dtype 改成np.int8(二进制只有0和1,用1字节足够,比默认float64省8倍内存)。
优化后的代码示例:
import numpy as np arr_size = 100 loop_size = 10000 # 用集合存储已生成数组的唯一整数标识 existing_arrays = set() # 用int8存储二进制矩阵,大幅降低内存占用 large_matrix = np.zeros((arr_size, loop_size), dtype=np.int8) flag = 0 def arr_generator(size): # 生成二进制数组,用int8更高效 return np.random.randint(0, 2, size, dtype=np.int8) while flag < loop_size: arr = arr_generator(arr_size) # 把二进制数组快速转成整数(比转字符串快很多) # 这里把数组当成高位在前的二进制数,顺序可以自己定,只要保持一致就行 power = 2 ** np.arange(arr_size, dtype=np.int64)[::-1] arr_id = arr.dot(power) if arr_id in existing_arrays: continue # 不存在则加入矩阵和集合 large_matrix[:, flag] = arr existing_arrays.add(arr_id) flag += 1
这个改动的核心是:
- 集合查找的时间复杂度从O(loop_size*arr_size)降到O(1)
- 矩阵内存占用直接砍到原来的1/8
2. 直接生成无重复的样本(适合特定场景)
如果你的loop_size小于等于2^arr_size(也就是所有可能的二进制数组总数),且2^arr_size不是特别大(比如arr_size≤25,2^25是3300万,内存能装下),那完全可以跳过“生成-判断-重复就重试”的循环,直接生成所有可能的唯一数组,再随机采样:
import numpy as np arr_size = 20 loop_size = 100000 # 生成所有可能的二进制数组对应的整数,随机打乱后取前loop_size个 all_unique_ids = np.arange(2 ** arr_size, dtype=np.int64) np.random.shuffle(all_unique_ids) selected_ids = all_unique_ids[:loop_size] # 把整数转回二进制数组填充矩阵 large_matrix = np.zeros((arr_size, loop_size), dtype=np.int8) for idx, num in enumerate(selected_ids): # 把整数转成固定长度的二进制字符串,再转成数组 binary_str = np.binary_repr(num, width=arr_size) large_matrix[:, idx] = np.array([int(c) for c in binary_str], dtype=np.int8)
这种方法完全避免了重复生成的浪费,适合需要大量无重复二进制数组的场景,唯一限制是2^arr_size不能超出内存承受范围。
3. 额外的小优化
- 如果
arr_generator是你自己实现的,尽量用numpy的向量化操作生成数组,别用Python循环,速度差很多 - 转整数的时候,用
np.int64类型存储power数组,避免大数溢出(Python的int虽然支持大数,但numpy的计算更快)
内容的提问来源于stack exchange,提问作者Lonitch
相关产品推荐
相关产品推荐

