This is the reproducible code:
a <- rep(1, 20)
a[c(1, 12, 15)] <- 0
b <- which(a == 0)
set.seed(123)
d <- round(runif(17) * 100)
I would like to append 0s to d to get the following result:
[1] 0 29 79 41 88 94 5 53 89 55 46 0 96 45 0 68 57 10 90 25
that is equal to d after appending 0s to each element which has index equal to b - 1.
I've seen append() accepts just one single "after" value, not more than one.
How could I do?
Please, keep in mind I cannot change the length of d because it is supposed it's the ouput of a quite long function, not a simple random sequence like in this example.
You can use negative subscripting to assign the non-zero elements to a new vector.
D <- numeric(length(c(b,d)))
D[-b] <- d
D
# [1] 0 29 79 41 88 94 5 53 89 55 46 0 96 45 0 68 57 10 90 25
Related
So, i'm doing a beginners challenge on HackerHank and, a strange behavior of ruby is boggling my mind.
The challenge is: find and count how many pairs there are in the array. (sock pairs)
Here's my code.
n = 100
ar = %w(50 49 38 49 78 36 25 96 10 67 78 58 98 8 53 1 4 7 29 6 59 93 74 3 67 47 12 85 84 40 81 85 89 70 33 66 6 9 13 67 75 42 24 73 49 28 25 5 86 53 10 44 45 35 47 11 81 10 47 16 49 79 52 89 100 36 6 57 96 18 23 71 11 99 95 12 78 19 16 64 23 77 7 19 11 5 81 43 14 27 11 63 57 62 3 56 50 9 13 45)
def sockMerchant(n, ar)
counter = 0
ar.each do |item|
if ar.count(item) >= 2
counter += ar.count(item)/2
ar.delete(item)
end
end
counter
end
print sockMerchant(n, ar)
The problem is, it doesn't count well. after running the function, in it's internal array ar still have countable pairs, and i prove it by running it again.
There's more. If you sort the array, it behaves differently.
it doesnt make sense to me.
you can check the behavior on this link
https://repl.it/repls/HuskyFrighteningNaturallanguage
You're deleting items from a collection while iterating over it - expect bad stuff to happen. In short, don't do that if you don't want to have such problems, see:
> arr = [1,2,1]
# => [1, 2, 1]
> arr.each {|x| puts x; arr.delete(x) }
# 1
# => [2]
We never get the 2 in our iteration.
A simple solution, that is a small variation of your code, could look as follows:
def sock_merchant(ar)
ar.uniq.sum do |item|
ar.count(item) / 2
end
end
Which is basically finding all unique socks, and then counting pairs for each of them.
Note that its complexity is n^2 as for each unique element n of the array, you have to go through the whole array in order to find all elements that are equal to n.
An alternative, first group all socks, then check how many pairs of each type we have:
ar.group_by(&:itself).sum { |k,v| v.size / 2 }
As ar.group_by(&:itself), short for ar.group_by { |x| x.itself } will loop through the array and create a hash looking like this:
{"50"=>["50", "50"], "49"=>["49", "49", "49", "49"], "38"=>["38"], ...}
And by calling sum on it, we'll iterate over it, summing the number of found elements (/2).
For example
I have one binary array with size of 9 as b = [0 1 0 1 0 1 1 1 1], Then another array 'm' with size of 7 as m = [21 28 36 45 45 66 66]. Here i want to change all the zeros of 'b' by 1st element of m then replace 1's of b by consecutive elements of 'm' so my output 1D array should be like k = [21 28 21 36 21 45 45 66 66].
Below is my code i really don't know where i did mistake please help me to solve this
b= [0 1 0 1 0 1 1 1 1];
b=b(:);
m = [21 28 36 45 45 66 66];
m = m(:);
k=zeros(size(b));
for i=1:length(b)
for j=2:length(m)
if b(i)==0
k(i)=m(1);
else
k(i)=m(j);
end
end
end
am getting output as
k = [21 66 21 66 21 66 66 66 66]
Use logical indexing instead - it is much faster and more readable:
b = [0 1 0 1 0 1 1 1 1];
m = [21 28 36 45 45 66 66];
k = zeros(size(b));
k(b==0) = m(1); % fill values where b=0 with m(1)
k(b==1) = m(2:sum(b)+1); % fill values where b=1 with consecutive m values
Result:
>> k
k =
21 28 21 36 21 45 45 66 66
I have a script to process weather polar radar data into cartesian coordinates and then plot it. I have tested each individual component and the individual components do what they're supposed to every time. Recently I had the need to streamline everything and so I put it in a script, but when I try to run my data through it, it kicks out an error message that I don't fully understand. Any help would be greatly appreciated. Thanks in advance. I am executing the script with the command radProcess(test, 1, ref).
My data looks like this (although this example has been scaled down from the 3600x800 data frame that it's in)-
V1 V2 V3 V4 V5 V6 V7 V8 V9 V10
1 -96 -75 -69 -62 51 40 47 50 52 47
2 -94 -80 -67 -57 53 37 44 51 54 50
3 -100 -81 -72 -61 54 42 50 48 56 50
4 -101 -82 -72 -63 55 43 40 47 50 48
5 -999 -78 -73 -59 55 40 46 49 54 54
6 -102 -81 -71 -59 51 37 44 52 55 57
7 -101 -79 -74 -59 54 43 42 47 55 47
8 -95 -80 -73 -59 52 40 48 54 58 54
9 -96 -78 -75 -58 57 44 39 50 47 55
10 -99 -79 -73 -59 57 45 46 56 55 53
I'm encountering an error message when I try to run my data that looks like this-
Error in radProcess(test, 10, ref) :
dims [product 864000] do not match the length of object [2880000]
In addition: Warning message:
In final.levl[cbind(z.rad, t.rad, r.rad)] * conversion.factor :
longer object length is not a multiple of shorter object length
The script can be seen below-
radProcess <- function(file, level, product){
## Convert file to 3 dimensional array format organized ##
## by scan level (10-top, 1-bottom of array) ##
print("Converting to 3D Array")
x.arr.vert <- array(unlist(file), dim = c(10,360,800))
x.arr.horz <- aperm(array(x.arr.vert, dim = c(360,10,800)), c(2,1,3))
final.levl <- x.arr.horz[ c(10:1),,]
## Create matrix of coordinates and values and then ##
## converts from polar to cartesian coordinates ##
print("Creating Matrix of Polar Coordinates")
mat <- which( (final.levl > -1000), arr.ind = TRUE)
z.rad <- mat[, 1]
t.rad <- mat[, 2]
r.rad <- mat[, 3]
print("Converting to Cartesian Coordinates")
theta.polar <- t.rad * pi / 180
r.polar <- r.rad * 0.075
x.cart <- r.polar * cos(theta.polar)
y.cart <- r.polar * sin(theta.polar)
## Reflectivity adjustment constant = .514245 ##
## Velocity adjustment constant = .1275628 ##
print("Determining Conversion Factor")
conversion.factor <- ifelse( (product == "ref"), yes = .514245, no = .1275628)
print("Copying Values from Array to Matrix")
value <- (final.levl[cbind(z.rad, t.rad, r.rad)] * conversion.factor)
Cart.Coord.Matrix <- matrix( NA, nrow = 2880000, ncol = 4)
Cart.Coord.Matrix <- cbind(z.rad, y.cart, x.cart, value)
## Create new matrix level wanted from transposed value matrix ##i
print("Reducing down to Level Wanted")
specified.level <- Cart.Coord.Matrix[z.rad == level,]
## Plot level values in Radar plot ##
print("Plotting Data Points")
x1<-specified.level[,3]
y2<-specified.level[,2]
z3<-specified.level[,4]
d1 <- data.frame(x1,y2,z3)
dg1 <-qplot(y2,x1,colour=z3,data=d1)
dg1 + scale_colour_gradientn(limits = c(0, 60), colours = rev(rainbow(10)))
}
Example of finished product
I have an array with three columns like this:
A B C
10 75 20
30 67 50
85 12 30
98 49 70
I have A and B values, and I want to get the corresponding C value.
For example if I enter (30,67) it should display 50.
Does Matlab have any trick for getting C value?
(my dataset is very large, and I need a fast way)
you can use ismember:
ABC = [10 75 20
30 67 50
85 12 30
98 49 70];
q = [30 67
85 12];
[~, locb] = ismember( q, ABC(:,1:2), 'rows' );
C = ABC(locb,3);
The result you get is
C =
50
30
Note that the code assume all pairs in q can be found in ABC.
Let your input data be defined as
data = [ 10 75 20
30 67 50
85 12 30
98 49 70];
values = [ 30 67];
This should be pretty fast:
index = data(:,1)==values(1) & data(:,2)==values(2); %// logical index to matching rows
result = data(index,3); %// third-column value for those rows
This gives all third-column values that match, should there be more than one.
If you want to specify several pairs of values at once, and obtain all matching results:
index = any(bsxfun(#eq, data(:,1).', values(:,1)), 1) & ...
any(bsxfun(#eq, data(:,2).', values(:,2)), 1);
result = data(index,3);
For example, given
data = [ 10 75 20
30 67 50
85 12 30
98 49 70
30 67 80 ];
values = [ 30 67
98 49];
the result would be
result =
50
70
80
You can create a sparse matrix. This solution only works if C does not contain any zeros and A and B are integers larger 0
A = [10 30 85 98]';
B = [75 67 12 49]';
C = [20 50 30 70]';
S = sparse(A,B,C);
S(10,75) % returns corresponding C-Value if found, 0 otherwise.
Try accumarray:
YourMatrix = accumarray([A B],C,[],#mean,true);
This way YourMatrix will be a matrix of size [max(A) max(B)], with the values of C at YourMatrix(A(ind),B(ind)), with ind the desired index of A and B:
A = [10 30 85 98]';
B = [75 67 12 49]';
C = [20 50 30 70]';
YourMatrix = accumarray([A B],C,[],#mean,true);
ind = 2;
YourMatrix(A(ind),B(ind))
ans =
50
This way, when there is a repetition in A B, it will return the corresponding C value, provided each unique pair of A B has the same C value. The true flag makes accumarray output a sparse matrix as opposed to a full matrix.
I have an array in MATLAB
For example
a = 1:100;
I want to select the first 4 element in every successive 10 elements.
In this example I want to b will be
b = [1,2,3,4,11,12,13,14, ...]
can I do it without for loop?
I read in the internet that i can select the element for each step:
b = a(1:10:end);
but this is not working for me.
Can you help me?
With reshape
%// reshaping your matrix to nx10 so that it has successive 10 elements in each row
temp = reshape(a,10,[]).'; %//'
%// taking first 4 columns and reshaping them back to a row vector
b = reshape(temp(:,1:4).',1,[]); %//'
Sample Run for smaller size (although this works for your actual dimensions)
a = 1:20;
>> b
b =
1 2 3 4 11 12 13 14
To vectorize the operation you must generate the indices you wish to extract:
a = 1:100;
b = a(reshape(bsxfun(#plus,(1:4)',0:10:length(a)-1),[],1));
Let's break down how this works. First, the bsxfun function. This performs a function, here it is addition (#plus) on each element of a vector. Since you want elements 1:4 we make this one dimension and the other dimension increases by tens. this will lead a Nx4 matrix where N is the number of groups of 4 we wish to extract.
The reshape function simply vectorizes this matrix so that we can use it to index the vector a. To better understand this line, try taking a look at the output of each function.
Sample Output:
>> b = a(reshape(bsxfun(#plus,(1:4)',0:10:length(a)-1),[],1))
b =
Columns 1 through 19
1 2 3 4 11 12 13 14 21 22 23 24 31 32 33 34 41 42 43
Columns 20 through 38
44 51 52 53 54 61 62 63 64 71 72 73 74 81 82 83 84 91 92
Columns 39 through 40
93 94