如何迭代构建bigsparser::SFBM矩阵?求替代构建方案
解决bigsparser构建大维度SFBM的替代方案
一、迭代创建SFBM(替代[]<-追加行)
SFBM不支持直接用[]<-添加行,但可以预先初始化空对象,再通过内置方法逐行写入稀疏数据:
- 先创建指定维度的空SFBM并指定磁盘存储路径:
library(bigsparser) # 初始化2500行、1e7列的空SFBM,指定存储文件前缀 sfbm <- SFBM(nrow = 2500, ncol = 1e7, backingfile = "my_large_matrix")
- 循环生成每行的非零数据,调用
add_rows写入:
for (i in 1:2500) { # 模拟生成当前行的非零列索引与对应值 non_zero_cols <- sample(1:1e7, size = 100) # 假设每行100个非零元素 non_zero_vals <- rnorm(length(non_zero_cols)) # 写入第i行的稀疏数据 sfbm$add_rows(i, non_zero_cols, non_zero_vals) }
二、合并同维度SFBM对象
如果已有多个列数相同的SFBM,可以用rbind.SFBM直接合并行:
# 假设sfbm1(1000行)、sfbm2(1500行)列数均为1e7 combined_sfbm <- rbind(sfbm1, sfbm2)
合并操作会直接在磁盘层面整合数据,无需加载全部内容到内存。
三、从CSV文件创建SFBM
根据CSV的存储格式,分两种方式处理:
- 稠密CSV(每行含全列数据,多数为0):逐行读取后提取非零元素写入:
sfbm <- SFBM(nrow = 2500, ncol = 1e7, backingfile = "from_dense_csv") con <- file("big_matrix.csv", "r") for (i in 1:2500) { line <- readLines(con, n = 1) row_vals <- as.numeric(strsplit(line, ",")[[1]]) # 筛选非零元素的位置与值 non_zero_idx <- which(row_vals != 0) non_zero_vals <- row_vals[non_zero_idx] sfbm$add_rows(i, non_zero_idx, non_zero_vals) } close(con)
- 稀疏CSV(每行存储行号、列号、值):分块读取后按行写入:
sfbm <- SFBM(nrow = 2500, ncol = 1e7, backingfile = "from_sparse_csv") library(data.table) # 分块读取CSV,每块处理10000行数据 fread("sparse_data.csv", sep = ",", chunk.size = 10000, function(chunk) { for (row_id in unique(chunk$row)) { row_chunk <- chunk[chunk$row == row_id] sfbm$add_rows(row_id, row_chunk$col, row_chunk$value) } })
注意事项
- 确保磁盘有足够空间存储SFBM的后端文件(存储大小由非零元素数量决定)。
- 全程保持分块/逐行处理逻辑,避免一次性加载全量数据到内存。
内容的提问来源于stack exchange,提问作者Karsten W.
相关产品推荐
相关产品推荐

