是否有向量化并行 max() 和 min()?

发布于 2024-10-31 03:49:34 字数 213 浏览 1 评论 0原文

我有一个带有“a”和“b”列的data.frame。我想添加名为“high”和“low”的列,其中包含 a 列和 b 列中的最高值和最低值。

有没有一种方法可以在不循环数据帧中的行的情况下执行此操作?

编辑:这是针对 OHLC 数据的,因此高列和低列应包含同一行上 a 和 b 之间的最高和最低元素,而不是整个列中的最高和最低元素。抱歉,如果这措辞不好。

I have a data.frame with columns "a" and "b". I want to add columns called "high" and "low" that contain the highest and the lowest among columns a and b.

Is there a way of doing this without looping over the lines in the dataframe?

edit: this is for OHLC data, and so the high and low column should contain the highest and lowest element between a and b on the same line, and not among the whole columns. sorry if this is badly worded.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

半步萧音过轻尘 2024-11-07 03:49:34

听起来您正在寻找 pmaxpmin (“并行”最大/最小值):

Extremes                 package:base                  R Documentation

Maxima and Minima

Description:

     Returns the (parallel) maxima and minima of the input values.

Usage:

     max(..., na.rm = FALSE)
     min(..., na.rm = FALSE)

     pmax(..., na.rm = FALSE)
     pmin(..., na.rm = FALSE)

     pmax.int(..., na.rm = FALSE)
     pmin.int(..., na.rm = FALSE)

Arguments:

     ...: numeric or character arguments (see Note).

   na.rm: a logical indicating whether missing values should be
          removed.

Details:

     ‘pmax’ and ‘pmin’ take one or more vectors (or matrices) as
     arguments and return a single vector giving the ‘parallel’ maxima
     (or minima) of the vectors.  The first element of the result is
     the maximum (minimum) of the first elements of all the arguments,
     the second element of the result is the maximum (minimum) of the
     second elements of all the arguments and so on.  Shorter inputs
     are recycled if necessary.  ‘attributes’ (such as ‘names’ or
     ‘dim’) are transferred from the first argument (if applicable).

Sounds like you're looking for pmax and pmin ("parallel" max/min):

Extremes                 package:base                  R Documentation

Maxima and Minima

Description:

     Returns the (parallel) maxima and minima of the input values.

Usage:

     max(..., na.rm = FALSE)
     min(..., na.rm = FALSE)

     pmax(..., na.rm = FALSE)
     pmin(..., na.rm = FALSE)

     pmax.int(..., na.rm = FALSE)
     pmin.int(..., na.rm = FALSE)

Arguments:

     ...: numeric or character arguments (see Note).

   na.rm: a logical indicating whether missing values should be
          removed.

Details:

     ‘pmax’ and ‘pmin’ take one or more vectors (or matrices) as
     arguments and return a single vector giving the ‘parallel’ maxima
     (or minima) of the vectors.  The first element of the result is
     the maximum (minimum) of the first elements of all the arguments,
     the second element of the result is the maximum (minimum) of the
     second elements of all the arguments and so on.  Shorter inputs
     are recycled if necessary.  ‘attributes’ (such as ‘names’ or
     ‘dim’) are transferred from the first argument (if applicable).
那些过往 2024-11-07 03:49:34

这是我使用 Rcpp 实现的版本。我将 pmin 与我的版本进行了比较,我的版本大约快了 3 倍。

library(Rcpp)

cppFunction("
  NumericVector min_vec(NumericVector vec1, NumericVector vec2) {
    int n = vec1.size();
    if(n != vec2.size()) return 0;
    else {
      NumericVector out(n);
      for(int i = 0; i < n; i++) {
        out[i] = std::min(vec1[i], vec2[i]);
      }
      return out;
    }
  }
")

x1 <- rnorm(100000)
y1 <- rnorm(100000)

microbenchmark::microbenchmark(min_vec(x1, y1))
microbenchmark::microbenchmark(pmin(x1, y1))

x2 <- rnorm(500000)
y2 <- rnorm(500000)

microbenchmark::microbenchmark(min_vec(x2, y2))
microbenchmark::microbenchmark(pmin(x2, y2))

100,000 个元素的 microbenchmark 函数输出为:

> microbenchmark::microbenchmark(min_vec(x1, y1))
Unit: microseconds
            expr     min       lq     mean  median       uq
 min_vec(x1, y1) 215.731 222.3705 230.7018 224.484 228.1115
     max neval
 284.631   100
> microbenchmark::microbenchmark(pmin(x1, y1))
Unit: microseconds
         expr     min       lq     mean  median      uq      max
 pmin(x1, y1) 891.486 904.7365 943.5884 922.899 954.873 1098.259
 neval
   100

对于 500,000 个元素:

> microbenchmark::microbenchmark(min_vec(x2, y2))
Unit: milliseconds
            expr      min       lq     mean   median       uq
 min_vec(x2, y2) 1.493136 2.008122 2.109541 2.140318 2.300022
     max neval
 2.97674   100
> microbenchmark::microbenchmark(pmin(x2, y2))
Unit: milliseconds
         expr      min       lq     mean   median       uq
 pmin(x2, y2) 4.652925 5.146819 5.286951 5.264451 5.445638
      max neval
 6.639985   100

因此您可以看到 Rcpp 版本更快。

您可以通过在函数中添加一些错误检查来使其更好,例如:检查两个向量是否具有相同的长度,或者它们是否具有可比性(不是字符与数字,或布尔与数字)。

Here's a version I implemented using Rcpp. I compared pmin with my version, and my version is roughly 3 times faster.

library(Rcpp)

cppFunction("
  NumericVector min_vec(NumericVector vec1, NumericVector vec2) {
    int n = vec1.size();
    if(n != vec2.size()) return 0;
    else {
      NumericVector out(n);
      for(int i = 0; i < n; i++) {
        out[i] = std::min(vec1[i], vec2[i]);
      }
      return out;
    }
  }
")

x1 <- rnorm(100000)
y1 <- rnorm(100000)

microbenchmark::microbenchmark(min_vec(x1, y1))
microbenchmark::microbenchmark(pmin(x1, y1))

x2 <- rnorm(500000)
y2 <- rnorm(500000)

microbenchmark::microbenchmark(min_vec(x2, y2))
microbenchmark::microbenchmark(pmin(x2, y2))

The microbenchmark function output for 100,000 elements is:

> microbenchmark::microbenchmark(min_vec(x1, y1))
Unit: microseconds
            expr     min       lq     mean  median       uq
 min_vec(x1, y1) 215.731 222.3705 230.7018 224.484 228.1115
     max neval
 284.631   100
> microbenchmark::microbenchmark(pmin(x1, y1))
Unit: microseconds
         expr     min       lq     mean  median      uq      max
 pmin(x1, y1) 891.486 904.7365 943.5884 922.899 954.873 1098.259
 neval
   100

And for 500,000 elements:

> microbenchmark::microbenchmark(min_vec(x2, y2))
Unit: milliseconds
            expr      min       lq     mean   median       uq
 min_vec(x2, y2) 1.493136 2.008122 2.109541 2.140318 2.300022
     max neval
 2.97674   100
> microbenchmark::microbenchmark(pmin(x2, y2))
Unit: milliseconds
         expr      min       lq     mean   median       uq
 pmin(x2, y2) 4.652925 5.146819 5.286951 5.264451 5.445638
      max neval
 6.639985   100

So you can see the Rcpp version is faster.

You could make it better by adding some error checking in the function, for instance: check that both vectors are the same length, or that they are comparable (not character vs. numeric, or boolean vs. numeric).

红尘作伴 2024-11-07 03:49:34

如果你的data.frame名称是dat。

dat$pmin <- do.call(pmin,dat[c("a","b")])
dat$pmax <- do.call(pmax,dat[c("a","b")])

If your data.frame name is dat.

dat$pmin <- do.call(pmin,dat[c("a","b")])
dat$pmax <- do.call(pmax,dat[c("a","b")])
南七夏 2024-11-07 03:49:34

另一种可能的解决方案:

set.seed(21)
Data <- data.frame(a=runif(10),b=runif(10))
Data$low <- apply(Data[,c("a","b")], 1, min)
Data$high <- apply(Data[,c("a","b")], 1, max)

Another possible solution:

set.seed(21)
Data <- data.frame(a=runif(10),b=runif(10))
Data$low <- apply(Data[,c("a","b")], 1, min)
Data$high <- apply(Data[,c("a","b")], 1, max)
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文