如何将np.isclose生成的布尔值存入形状为(60,6,6,4,72)的numpy数组
解决方案
完全不需要用np.append/np.insert做动态拼接,要么直接用numpy广播特性一步生成目标数组,要么提前预分配内存逐位赋值即可。
最优方案:利用广播特性一步生成(无循环,性能最高)
你的核心需求是将Matrix中每个标量值,与Matrix2中所有4*72个值逐一做isclose判断,直接做维度扩展后广播计算即可:
import numpy as np # 原始初始化代码 Matrix = np.random.randint(5, size=(60, 6, 6)) arr = np.random.randint(5, size=(1, 240)) arr1 = np.random.randint(5, size=(1, 240)) arr2 = np.random.randint(5, size=(1, 240)) arr3 = np.random.randint(5, size=(1, 240)) # 拼接得到Matrix2,注意二维数组切片要指定维度,原代码的切片写法会导致形状异常 kkk = 3 vvv = 79 Matrix2 = np.concatenate([ arr[:, kkk:vvv], arr1[:, kkk:vvv], arr2[:, kkk:vvv], arr3[:, kkk:vvv] ], axis=0) # 输出形状为(4,72),符合要求 # 维度扩展后直接广播计算,一步得到目标形状数组 result = np.isclose( Matrix[..., np.newaxis, np.newaxis], # 扩展为(60,6,6,1,1) Matrix2[np.newaxis, np.newaxis, np.newaxis, ...], # 扩展为(1,1,1,4,72) rtol=0.005, atol=0.0 ) # 此时result形状就是你需要的(60,6,6,4,72)
如果需要最终形状为(72,4,6,6,60),直接做轴转置即可:
result = result.transpose(4,3,2,1,0)
兼容原有循环逻辑的实现
如果一定要保留循环写法,提前预分配内存再逐位赋值即可:
import numpy as np Matrix = np.random.randint(5, size=(60, 6, 6)) arr = np.random.randint(5, size=(1, 240)) arr1 = np.random.randint(5, size=(1, 240)) arr2 = np.random.randint(5, size=(1, 240)) arr3 = np.random.randint(5, size=(1, 240)) # 预分配目标形状的布尔数组,默认填充False result = np.zeros((60,6,6,4,72), dtype=bool) kkk = 3 vvv = 79 while True: Matrix2 = np.concatenate([ arr[:, kkk:vvv], arr1[:, kkk:vvv], arr2[:, kkk:vvv], arr3[:, kkk:vvv] ], axis=0) for i in range(Matrix.shape[0]): for j in range(Matrix.shape[1]): for z in range(Matrix.shape[2]): for v in range(Matrix2.shape[0]): for vv in range(Matrix2.shape[1]): result[i,j,z,v,vv] = np.isclose(Matrix[i,j,z], Matrix2[v,vv], rtol=0.005, atol=0.0) if j >= 5: kkk +=4 vvv +=4 if i ==59: break
原代码错误说明
- 二维数组切片写法错误:
arr[kkk:vvv]是对第一维做切片,而arr第一维长度只有1,会得到空数组或者形状异常,正确写法是arr[:, kkk:vvv] - 函数定义写在多层循环内部,每次循环都会重复定义函数,完全没有必要
- 循环层级错乱,Matrix2拼接逻辑不需要放在最内层循环,每次迭代生成一次即可
内容的提问来源于stack exchange,提问作者Mathias Albrechtsen
相关产品推荐
相关产品推荐

