用零替换负值 [英] Replace negative values by zero

查看:85
本文介绍了用零替换负值的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我们想将数组中所有为负的值设置为零。



我尝试了很多方法,但尚未实现有效的解决方案。
我想到了带条件的for循环,但这似乎不起作用。

  #pred_precipitation是我们的数组
pred_precipitation< -rnorm(25,2,4)

for(i in nrow(pred_precipitation))
{
if(pred_precipitation [i]< 0 ){pred_precipitation [i] = 0}
else {pred_precipitation [i] = pred_precipitation [i]}
}


解决方案

感谢可复制的示例。这是相当基本的R东西。您可以分配给向量的选定元素(请注意,数组具有维,并且给定的是向量而不是数组):

 > pred_precipitation [pred_precipitation< 0]<-0 
> pred_precipitation
[1] 1.2091281 0.0000000 7.7665555 0.0000000 0.0000000 0.0000000 0.5151504 0.0000000 1.8281251
[10] 0.5098688 2.8370263 0.4895606 1.5152191 4.1740177 7.1527742 2.8992215 4.5322934 6.7180530
[19] 0.0000000 1.1914052 3.6152333 0.0000000 0.3778b 0.0000000 1.4 b

基准战争!



@James找到了一种甚至更快的方法,并将其留在了评论中。我赞成他,只要是因为我知道他的胜利将是短暂的。



首先,我尝试进行编译,但这似乎无济于事:

  p<-rnorm(10000)
gsk3<-函数(x){x [x< 0]< ;-0; x}
jmsigner<-函数(x)ifelse(x< 0,0,x)
joshua<-函数(x)pmin(x,0)
james<- function(x)(abs(x)+ x)/ 2
库(编译器)
gsk3.c<-cmpfun(gsk3)
jmsigner.c<-cmpfun(jmsigner)
joshua.c<-cmpfun(约书亚)
james.c<-cmpfun(詹姆斯)

微型基准(joshua(p),joshua.c(p), gsk3(p),gsk3.c(p),jmsigner(p),james(p),jmsigner.c(p),james.c(p))
expr min lq中位数uq max
1 gsk3.c(p)251.782 255.0515 266.8685 269.5205 457.998
2 gsk3(p)256.262 261.6105 270.7340 281.3560 2940.486
3 james.c(p)38.418 41.3770 43.3020 45.6160 132.342
4 james(p )38.934 42.1965 43.5700 47.2085 4524.303
5 jmsigner.c(p)2047.739 2145.9915 2198.6170 2291.8475 4879.418
6 jmsigner(p)2047.502 2169.9555 2258.6225 2405.0730 5064.334
7 joshua.c(p)237.570。 265.2545 376.684
8约书亚(p)237.545 244。 8635 255.1690 271.9910 430.566



但是请稍等!德克写了这个Rcpp的东西。完全没有能力的C ++可以阅读他的JSS论文,改编他的示例并编写所有这些中最快的功能吗?敬请关注,亲爱的听众。

 库(内联)
cpp_if_src<-'
Rcpp :: NumericVector xa(a);
int n_xa = xa.size();
for(int i = 0; i< n_xa; i ++){
if(xa [i] <0)xa [i] = 0;
}
return xa;
'
cpp_if<-cxxfunction(signature(a = numeric),cpp_if_src,plugin = Rcpp)
microbenchmark(joshua(p),joshua.c(p), gsk3(p),gsk3.c(p),jmsigner(p),james(p),jmsigner.c(p),james.c(p),cpp_if(p))
expr min lq中位数uq最大值
1 cpp_if(p)8.233 10.4865 11.6000 12.4090 69.512
2 gsk3(p)170.572 172.7975 175.0515 182.4035 2515.870
3 james(p)37.074 39.6955 40.5720 42.1965 2396.758
4 jmsigner( p)1110.313 1118.9445 1133.4725 1164.2305 65942.680
5 joshua(p)237.135 240.1655 243.3990 250.3660 2597.429



那是肯定的,队长。 / p>

这将修改输入 p ,即使您未分配输入。如果要避免这种行为,则必须克隆:

  cpp_ifclone_src<-'
Rcpp :: NumericVector xa(Rcpp :: clone(a));
int n_xa = xa.size();
for(int i = 0; i if(xa [i] <0)xa [i] = 0;
}
return xa;
'
cpp_ifclone<-cxxfunction(signature(a = numeric),cpp_ifclone_src,plugin = Rcpp)

不幸的是,这扼杀了速度优势。


We want to set all values in an array zero that are negative.

I tried out a a lot of stuff but did not yet achieve a working solution. I thought about a for loop with condition, however this seems not to work.

#pred_precipitation is our array
pred_precipitation <-rnorm(25,2,4)     

for (i in nrow(pred_precipitation))
{
  if (pred_precipitation[i]<0) {pred_precipitation[i] = 0}
  else{pred_precipitation[i] = pred_precipitation[i]}
}

解决方案

Thanks for the reproducible example. This is pretty basic R stuff. You can assign to selected elements of a vector (note an array has dimensions, and what you've given is a vector not an array):

> pred_precipitation[pred_precipitation<0] <- 0
> pred_precipitation
 [1] 1.2091281 0.0000000 7.7665555 0.0000000 0.0000000 0.0000000 0.5151504 0.0000000 1.8281251
[10] 0.5098688 2.8370263 0.4895606 1.5152191 4.1740177 7.1527742 2.8992215 4.5322934 6.7180530
[19] 0.0000000 1.1914052 3.6152333 0.0000000 0.3778717 0.0000000 1.4940469

Benchmark wars!

@James has found an even faster method and left it in a comment. I upvoted him, if only because I know his victory will be short-lived.

First, I try compiling, but that doesn't seem to help anyone:

p <- rnorm(10000)
gsk3 <- function(x) { x[x<0] <- 0; x }
jmsigner <- function(x) ifelse(x<0, 0, x)
joshua <- function(x) pmin(x,0)
james <- function(x) (abs(x)+x)/2
library(compiler)
gsk3.c <- cmpfun(gsk3)
jmsigner.c <- cmpfun(jmsigner)
joshua.c <- cmpfun(joshua)
james.c <- cmpfun(james)

microbenchmark(joshua(p),joshua.c(p),gsk3(p),gsk3.c(p),jmsigner(p),james(p),jmsigner.c(p),james.c(p))
           expr      min        lq    median        uq      max
1     gsk3.c(p)  251.782  255.0515  266.8685  269.5205  457.998
2       gsk3(p)  256.262  261.6105  270.7340  281.3560 2940.486
3    james.c(p)   38.418   41.3770   43.3020   45.6160  132.342
4      james(p)   38.934   42.1965   43.5700   47.2085 4524.303
5 jmsigner.c(p) 2047.739 2145.9915 2198.6170 2291.8475 4879.418
6   jmsigner(p) 2047.502 2169.9555 2258.6225 2405.0730 5064.334
7   joshua.c(p)  237.008  244.3570  251.7375  265.2545  376.684
8     joshua(p)  237.545  244.8635  255.1690  271.9910  430.566

But wait! Dirk wrote this Rcpp thing. Can a complete C++ incompetent read his JSS paper, adapt his example, and write the fastest function of them all? Stay tuned, dear listeners.

library(inline)
cpp_if_src <- '
  Rcpp::NumericVector xa(a);
  int n_xa = xa.size();
  for(int i=0; i < n_xa; i++) {
    if(xa[i]<0) xa[i] = 0;
  }
  return xa;
'
cpp_if <- cxxfunction(signature(a="numeric"), cpp_if_src, plugin="Rcpp")
microbenchmark(joshua(p),joshua.c(p),gsk3(p),gsk3.c(p),jmsigner(p),james(p),jmsigner.c(p),james.c(p), cpp_if(p))
         expr      min        lq    median        uq       max
1   cpp_if(p)    8.233   10.4865   11.6000   12.4090    69.512
2     gsk3(p)  170.572  172.7975  175.0515  182.4035  2515.870
3    james(p)   37.074   39.6955   40.5720   42.1965  2396.758
4 jmsigner(p) 1110.313 1118.9445 1133.4725 1164.2305 65942.680
5   joshua(p)  237.135  240.1655  243.3990  250.3660  2597.429

That's affirmative, captain.

This modifies the input p even if you don't assign to it. If you want to avoid that behavior, you have to clone:

cpp_ifclone_src <- '
  Rcpp::NumericVector xa(Rcpp::clone(a));
  int n_xa = xa.size();
  for(int i=0; i < n_xa; i++) {
    if(xa[i]<0) xa[i] = 0;
  }
  return xa;
'
cpp_ifclone <- cxxfunction(signature(a="numeric"), cpp_ifclone_src, plugin="Rcpp")

Which unfortunately kills the speed advantage.

这篇关于用零替换负值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆