将行中所有元素除以该行最大值 - 更快速的方法

5

我需要对一个数据框进行缩放。


按行分别将每个元素除以该行中的最大数,但如果该行包含数字1,则不进行操作。

我使用以下方法:

post_df <- df # original dataframe
for(i in 1:nrow(df)){
    if (! 1 %in% df[i,]) {
        post_df[i,] <- df[i,]/max(df[i,])
    }
}

我想知道是否有更快的方法,可以缩短一些时间,因为我在一个大数据框中运行此程序 86000 行 * 500 列

例如:

5 行,5 列

第 1 行:将所有元素除以 0.7
第 2 行:将所有元素除以 0.4
第 3 行:忽略
第 4 行:忽略
第 5 行:忽略
enter image description here


没有样本数据,很难理解你所谓的“包含数字1”的意思。一般来说,应该避免像你正在做的那样处理每个单独元素。使用向量操作。 - biocyberman
给我一秒钟,我会举个例子。 - Panos Kalatzantonakis
3个回答

3
根据描述,我们只需要将那些没有1的行进行缩放。基于rowSums创建一个逻辑索引('i1'),然后使用'i1'对数据集进行子集化,并使用pmax获取每行的最大值,用该子集除以最大值并将其分配回去。
i1 <- !rowSums(df==1)>0
df[i1,] <- df[i1,]/do.call(pmax, df[i1,])

数据

set.seed(24)
df <- as.data.frame(matrix(sample(1:8, 10*5, replace = TRUE), ncol=5))

1
谢谢大家,akrun的方法是最快的。 - Panos Kalatzantonakis

1
示例数据:只有前两行中有1。
df <- iris[1:5, 1:4]
df[2,3] <- 1
df[1,1] <- 1
df

# Sepal.Length Sepal.Width Petal.Length Petal.Width
# 1          1.0         3.5          1.4         0.2
# 2          4.9         3.0          1.0         0.2
# 3          4.7         3.2          1.3         0.2
# 4          4.6         3.1          1.5         0.2
# 5          5.0         3.6          1.4         0.2

计算

res <- sapply(1:nrow(df), function(x) if(any(df[x, ] == 1)) {
  df[x, ]
} else {
  df[x, ]/ max(df[x, ])
 }
)

t(res)


# Sepal.Length Sepal.Width Petal.Length Petal.Width
#  1            3.5         1.4          0.2
#  4.9          3           1            0.2
#  1            0.6808511   0.2765957    0.04255319
#  1            0.673913    0.326087     0.04347826
#  1            0.72        0.28         0.04

除了值为1的行,其他行都被该行的最大值除。

1
以下是什么情况?
set.seed(2017)
# Sample data
mat <- matrix(sample(5*10), ncol = 5)
mat;
#      [,1] [,2] [,3] [,4] [,5]
# [1,]   47   49   42   46   11
# [2,]   27    1   41   38   37
# [3,]   23   39   40   28   13
# [4,]   14   16   21    4   43
# [5,]   36   18    6   33    9
# [6,]   35   50   48   10   29
# [7,]    2   45   15   22    7
# [8,]   19   24    8   34    5
# [9,]   20   31   44    3   25
#[10,]   12   26   32   30   17


# Scale by row length if row does not contain 1
mat.scaled <- t(apply(mat, 1, function(x) if (1 %in% x) x else x / length(x)))
mat.scaled;
#     [,1] [,2] [,3] [,4] [,5]
# [1,]  9.4  9.8  8.4  9.2  2.2
# [2,] 27.0  1.0 41.0 38.0 37.0
# [3,]  4.6  7.8  8.0  5.6  2.6
# [4,]  2.8  3.2  4.2  0.8  8.6
# [5,]  7.2  3.6  1.2  6.6  1.8
# [6,]  7.0 10.0  9.6  2.0  5.8
# [7,]  0.4  9.0  3.0  4.4  1.4
# [8,]  3.8  4.8  1.6  6.8  1.0
# [9,]  4.0  6.2  8.8  0.6  5.0
#[10,]  2.4  5.2  6.4  6.0  3.4

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接