【问题标题】:A more efficient way to populate a matrix一种更有效的填充矩阵的方法
【发布时间】:2019-03-14 20:18:34
【问题描述】:

我正在尝试cbind 一个非常大的矩阵,其中包含我拥有的数据框,但由于矩阵的大小,我遇到了内存问题。

我有数据:

set.seed(123)
df1 <- data.frame(replicate(5, sample(1:20, 10, rep=TRUE)))
colnames(df1) <- c("col1", "col2", "col3", "col4", "important_col")
df2 <- data.frame(replicate(20, sample(0:0, nrow(df1), rep=TRUE)))
colnames(df2) <- gsub("X", "", colnames(df2))
df_fin <- cbind(df1, df2)

以下在一个小样本上可以按我的意愿工作,但是当应用于数十万行和 1000 列以上时,我会遇到内存问题。

vecp <- colnames(df2)

imp_col <- df1$important_col

matrix <-  matrix(vecp, byrow = TRUE,
                           nrow = length(imp_col),
                           ncol = length(vecp),
                           dimnames = list(1:length(imp_col), vecp))

d <- ifelse(matrix == imp_col, 1, 0)


df_fin <- cbind(df1, d)

我试图在d &lt;- ifelse(matrix == imp_col, 1, 0) 行使代码更高效(是我有内存问题的地方)。

在我应用ifesle 语句之前,有没有办法让矩阵成为sparse 矩阵。

我构建了一个如下的矩阵:

   col1 col2 col3 col4 important_col 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
1    11   14    3   11             1 0 0 0 0 0 0 0 0 0  0  0  0  0  0  0  0  0  0  0  0
2     1    1   19   15             4 0 0 0 0 0 0 0 0 0  0  0  0  0  0  0  0  0  0  0  0
3     3   17   10   10             6 0 0 0 0 0 0 0 0 0  0  0  0  0  0  0  0  0  0  0  0
4    13   10    8   17            10 0 0 0 0 0 0 0 0 0  0  0  0  0  0  0  0  0  0  0  0
5    18    5    3   18            19 0 0 0 0 0 0 0 0 0  0  0  0  0  0  0  0  0  0  0  0
6    11   10    9    5            17 0 0 0 0 0 0 0 0 0  0  0  0  0  0  0  0  0  0  0  0
7     5   11   18   16            17 0 0 0 0 0 0 0 0 0  0  0  0  0  0  0  0  0  0  0  0
8     5    8   13    8             6 0 0 0 0 0 0 0 0 0  0  0  0  0  0  0  0  0  0  0  0
9    10    1    7   16            12 0 0 0 0 0 0 0 0 0  0  0  0  0  0  0  0  0  0  0  0
10    4   17   17    3             4 0 0 0 0 0 0 0 0 0  0  0  0  0  0  0  0  0  0  0  0

最终产品是这样的:

   col1 col2 col3 col4 important_col 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
1     6   20   18   20             3 0 0 1 0 0 0 0 0 0  0  0  0  0  0  0  0  0  0  0  0
2    16   10   14   19             9 0 0 0 0 0 0 0 0 1  0  0  0  0  0  0  0  0  0  0  0
3     9   14   13   14             9 0 0 0 0 0 0 0 0 1  0  0  0  0  0  0  0  0  0  0  0
4    18   12   20   16             8 0 0 0 0 0 0 0 1 0  0  0  0  0  0  0  0  0  0  0  0
5    19    3   14    1             4 0 0 0 1 0 0 0 0 0  0  0  0  0  0  0  0  0  0  0  0
6     1   18   15   10             3 0 0 1 0 0 0 0 0 0  0  0  0  0  0  0  0  0  0  0  0
7    11    5   11   16             5 0 0 0 0 1 0 0 0 0  0  0  0  0  0  0  0  0  0  0  0
8    18    1   12    5            10 0 0 0 0 0 0 0 0 0  1  0  0  0  0  0  0  0  0  0  0
9    12    7    6    7             6 0 0 0 0 0 1 0 0 0  0  0  0  0  0  0  0  0  0  0  0
10   10   20    3    5            18 0 0 0 0 0 0 0 0 0  0  0  0  0  0  0  0  0  1  0  0

然后我将其制成一个稀疏矩阵。

【问题讨论】:

  • 这有帮助吗(纯粹是为了加速 ifelse,而不是为了之前制作稀疏矩阵......)? stackoverflow.com/questions/50016056/…
  • 额外的包'bigmemory'(特别是big.matrix那里)可能是一个选项?

标签: r


【解决方案1】:

问题是d 与您的矩阵大小相同,因此如果您的矩阵很大,那么您将拥有其中两个。一种可能的选择(尽管可能更慢)是遍历列并一次更改一个,这只会创建与矩阵的一列大小相同的对象。你可以试试这个:

for (i in 1:ncol(matrix)) matrix[, i] <- matrix[, i] == imp_col

表达式返回一个布尔值,但如果您的矩阵由整数组成,那么它们将被转换为 0 和 1。

【讨论】:

  • 谢谢,它有效,就像你提到的那样慢,但它有效!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-07-19
  • 2019-06-29
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多