Vector converted all negative values to zero
That's because push_back
puts new elements onto the end of the vector.
You can see the effect by running i
to 9
: the negative numbers will occupy v[5]
to v[9]
.
Writing
std::vector<int> v{-1, -2, -3, -4, -5};
instead is a particularly elegant fix.
How to replace all negative values in vector by 0 in R
Generate some data
x = rnorm(50)
then either
x = ifelse(x > 0, 1, 0)
or
x[x < 0] = 0
x[x > 0] = 1
Or even better
as.numeric (x>0)
However since the standard normal is symmetric about 0, why not simulate directly via
sample(0:1, 50, replace=TRUE)
Replace negative values by zero
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.
How to transform negative elements to zero without a loop?
a = a.clip(min=0)
What is the fastest way to replace negative values with 0 and values greater than 1 with 1 in an array using Python?
You want to use np.clip
:
>>> import numpy as np
>>> list_values = [-0.01, 0, 0.5, 0.9, 1.0, 1.01]
>>> arr = np.array(list_values)
>>> np.clip(arr, 0.0, 1.0)
array([0. , 0. , 0.5, 0.9, 1. , 1. ])
This is likely the fastest approach, if you can ignore the cost of converting to an array. Should be a lot better for larger lists/arrays.
Involving pandas
in this operation isn't the way to go unless you eventually want a pandas data structure.
Replacing all negative elements with zero eigen3 c++
A nicer and more efficient way than your proposed method would be to use the select
method.
result = (result.array() < 0).select(0, result);
Subsetting the closest number to zero for negative numbers only
If you convert the data frame to long format you can do this a little bit more compactly. (It also generalizes to any number of accident types, missing accident types within id
, etc. ...)
sfun <- function(x) {
x <- na.omit(x)
## if x has no non-NA values, all(x>0) will be TRUE
if (all(x>0)) NA_real_ else max(x[x<=0])
}
(df
## convert to long format
%>% pivot_longer(-id)
%>% group_by(id)
## apply summary function to values within id
%>% summarise(magic=sfun(value))
## add original columns back in
%>% full_join(df, by = "id")
)
The only difference is that the magic
column is before the rest of the data, not after it (you could add a call to relocate()
if you like)
negative values in my probability vector
You need to transform all the values of the input array into positive values, a few alternatives are:
- Convert all the negatives to 0, function
zeroed
- Shift all the values by the absolute value of the minimum element, function
shifted
- Apply the exponential function to the values, function
exponential
After you have converted the values of the input array you can use your function as usual, follow the definition of the transformation functions:
def zeroed(arr):
return arr.clip(min=0)
def shifted(arr):
return arr + abs(np.min(arr))
def exponential(arr):
return np.exp(arr)
In your function you can use the transformation as follows:
def createProbabilityVector(inputArray):
vector = inputArray
probabilityVector = np.zeros(vector.shape)
for x in range(vector.shape[0]):
new_vector = zeroed(vector[x])
vectorSum = sum(new_vector)
probabilityVector[[x]] = new_vector / vectorSum
return probabilityVector
The function zeroed
can be replace by shifted
or exponential
, for the input:
array = np.array([[1.62242568, 1.27356428, -1.88008155, 1.37183247],
[-1.10638392, 0.18420085, -1.68558966, -1.59951709],
[1.79166467, -0.21911691, -1.29066019, 0.4565108],
[-0.20459109, 1.59912774, 0.47735207, 1.6398782]])
These are the results for the function zeroed
:
[[0.38015304 0.29841079 0. 0.32143616]
[0. 1. 0. 0. ]
[0.79694165 0. 0. 0.20305835]
[0. 0.43029432 0.1284462 0.44125948]]
for shifted
:
[[0.35350056 0.31829072 0. 0.32820872]
[0.22847732 0.73756992 0. 0.03395275]
[0.52233595 0.18158552 0. 0.29607853]
[0. 0.41655061 0.15748787 0.42596152]]
and exponential
:
[[0.39778013 0.28063027 0.01198184 0.30960776]
[0.17223667 0.62606504 0.09651165 0.10518664]
[0.69307072 0.09279107 0.03177905 0.18235916]
[0.06504215 0.39494808 0.12863496 0.41137482]]
Related Topics
Given an Integer N. What Is the Smallest Integer Greater Than N That Only Has 0 or 1 as Its Digits
Most Efficient Way to Compare a Variable to Multiple Values
How to Read and Parse CSV Files in C++
How to Print a Double Value With Full Precision Using Cout
Read Whole Ascii File into C++ Std::String
Best Practices For Circular Shift (Rotate) Operations in C++
Overloading Friend Operator≪≪ For Template Class
Virtual/Pure Virtual Explained
Usr/Bin/Ld: Cannot Find -L≪Nameofthelibrary≫
Initialization of All Elements of an Array to One Default Value in C++
How to Properly Clean Up Elements from Vectors of Object Pointers
Print a Binary Tree in a Pretty Way
What Is a Smart Pointer and When Should I Use One
How to Detect Unsigned Integer Overflow
Does a Const Reference Class Member Prolong the Life of a Temporary
What Is the Type of String Literals in C and C++
Problems Importing Libraries to My C++ Project, How to Fix This