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

时间:2017-10-26 11:23:57

标签: r

我需要缩放dataframe 我需要遵循的流程如下:

  

将行中的所有元素除以该行中的最大数字,除非该行包含数字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 rows *500 cols中运行它。

E.g

5行,5列

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

3 个答案:

答案 0 :(得分:3)

根据说明,我们只需要a那些没有的行1.根据array([[0, 0, 1, 0], [0, 0, 1, 1], [0, 0, 1, 1], [1, 0, 1, 0]]) 创建逻辑索引(&#39; i1&#39;)然后使用&#39; i1&#39;对数据集进行子集,用a = np.array([[int(i) for i in r] for r in np.sort(np.apply_along_axis(lambda r: ''.join([str(c) for c in r]), 0, a))]) 得到每行的scale,除以子集并将其分配回子集

rowSums

数据

max

答案 1 :(得分: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的行外,其余部分除以该行的最大值。

答案 2 :(得分: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