python - 计算大矩阵的均值和协方差(300000 x 70000)
问题描述
我正在使用 Numpy 并尝试计算大矩阵(300000 x 70000)的均值和协方差。我有 32GB 大小的可用内存。就计算效率和易于实施而言,这项任务的最佳实践是什么?
我目前的实现如下:
def compute_mean_variance(mat, chunk_size):
row_count = mat.row_count
col_count = mat.col_count
# maintain the `x_sum`, `x2_sum` array
# mean(x) = x_sum / row_count
# var(x) = x2_sum / row_count - mean(x)**2
x_sum = np.zeros([1, col_count])
x2_sum = np.zeros([1, col_count])
for i in range(0, row_count, chunk_size):
sub_mat = mat[i:i+chunk_size, :]
# in-memory sub_mat of size chunk_size x num_cols
sub_mat = sub_mat.read().val
x_sum += np.sum(sub_mat, 0)
x2_sum += x2_sum + np.sum(sub_mat**2, 0)
x_mean = x_sum / row_count
x_var = x2_sum / row_count - x_mean ** 2
return x_mean, x_var
有什么改进建议吗?
我发现下面的实现应该更容易理解。它还使用 numpy 计算列块的平均值和标准差。所以它应该更有效并且在数值上更稳定。
def compute_mean_std(mat, chunk_size):
row_count = mat.row_count
col_count = mat.col_count
mean = np.zeros(col_count)
std = np.zeros(col_count)
for i in xrange(0, col_count, chunk_size):
sub_mat = mat[:, i : i + chunk_size]
# num_samples x chunk_size
sub_mat = sub_mat.read().val
mean[i : i + chunk_size] = np.mean(sub_mat, axis=0)
std[i : i + chunk_size] = np.std(sub_mat, axis=0)
return mean, std
解决方案
所以我在大学有一个项目,涉及不同矩阵乘法算法的时间复杂度测试。
我在这里上传了源代码。
我发现的优化之一是您可以通过更改 for 循环的结构来优化数组访问,以一次只关注行而不是遍历列。这是由于缓存在空间局部性上的行为方式(即您的计算机尝试针对二维数组中并排而不是逐行的数组元素进行优化)
此外,如果这些是“稀疏”矩阵(很多零元素),您可以更改数据结构以仅记录非零元素。
显然,如果给定一个普通矩阵,将它们转换为稀疏矩阵的计算可能不值得,但我只是认为这些观察值得分享:)
推荐阅读
- c++ - 是否有预处理器方法可以从调试符号中删除代码段?
- vba - 格式 - 预期的数组
- r - 使用 scale_fill_gradientn 将特定颜色分配给条形图中的确定值
- ios - Xcode 11.2 场景编辑器是否允许添加组件?
- excel - Excel VBA 从域中获取 IP 地址
- reactjs - 浅渲染返回空对象,wrapper.debug() 显示完全渲染的组件
- .net - 如何在服务器 ubuntu 18.04.3 LTS 上启动 PuppeteerSharp?System.ComponentModel.Win32Exception (13):权限被拒绝
- php - 当woocommerce中的产品数量增加/减少时,如何从商店页面更新购物车?
- ruby-on-rails - 链式 ruby on rails 查询返回那些不是 nil 的
- sql - 没有标识列时删除重复值