for extracting all nonzero elemnts of an one dimentional array, we do the following:
One_D = [1,4,5,0,0,4,7,0,2,6]
One_D[One_D .> 0]
How to do a similar thing for a two or more than 2 dimentinal vectore array?
two_D = [[1,0,2,3,0],[4,0,5,0,6]]
this two_D[two_D .> 0] obviously is incorrect. So, what esle we can try?
Your two_D is not 2 dimensional, but it is a vector of vectors. You can use then broadcasted filter:
julia> filter.(>(0), two_D)
2-element Vector{Vector{Int64}}:
[1, 2, 3]
[4, 5, 6]
If instead your two_D were a matrix like this:
julia> mat = [[1,0,2,3,0] [4,0,5,0,6]]
5×2 Matrix{Int64}:
1 4
0 0
2 5
3 0
0 6
You can still use filter but without broadcasting. In this case you will get a flat vector of found elements:
julia> filter(>(0), mat)
6-element Vector{Int64}:
1
2
3
4
5
6
Related
I have been struggling with a task in R for some time, which seems to be easy.
suppose this is my sample data:
df <- data.frame(a=c(2,2,7),b=c(1,4,3),c=c(9,5,3))
v <- c(1,2,3)
now I would like to multiply each column by the corresponding vector element e.g. first column by v[1], second column by v[2]etc..
expected output:
a b c
1 2 2 27
2 2 8 15
3 7 6 9
The target data is much larger and consists of integers and floating point numbers.
Thank you in advance!
You can use sweep:
sweep(df, 2, v, FUN="*")
Second option is mapply:
mapply(`*`, df, v)
Or with transposing:
t(t(df)*v)
You can try col
> v[col(df)] * df
a b c
1 2 2 27
2 2 8 15
3 7 6 9
apply(df, 1, function(x) x * v) |> t()
or
t(apply(df, 1, function(x) x * v))
I would like to use Julia's map function to mimic a nested list comprehension. This ability would be particularly useful for parallel mapping (pmap).
For example, this nested list comprehension
[x+y for x in [0,10] for y in [1,2,3]]
produces the nice result
6-element Array{Int64,1}:
1
2
3
11
12
13
and this
[x+y for x in [0,10], y in [1,2,3]]
produces the equally nice
2×3 Array{Int64,2}:
1 2 3
11 12 13
Either of these outcomes are satisfactory for my purposes.
Now here is my best effort at replicating these outcomes with map
map([0,10]) do x
map([1,2,3]) do y
x + y
end
end
which yields the correct results, just not in a form I admire:
2-element Array{Array{Int64,1},1}:
[1, 2, 3]
[11, 12, 13]
Now I know there are brute-force ways get the outcome I want, such as hcat/vcat'ing the output or manipulating the input into a matrix, but I'd like to know if there exists a solution as elegant as the nested list comprehension.
The simplest way I can think of is to use comprehensions and combine them with map (low benefit) or pmap (here you get the real value).
On Julia 0.7 (use the fact that in this release you have destructuring in function arguments functionality):
julia> map(((x,y) for x in [0,10] for y in [1,2,3])) do (x,y)
x+y
end
6-element Array{Int64,1}:
1
2
3
11
12
13
julia> map(((x,y) for x in [0,10], y in [1,2,3])) do (x,y)
x+y
end
2×3 Array{Int64,2}:
1 2 3
11 12 13
On Julia 0.6.2 (less nice):
julia> map(((x,y) for x in [0,10] for y in [1,2,3])) do v
v[1]+v[2]
end
6-element Array{Int64,1}:
1
2
3
11
12
13
julia> map(((x,y) for x in [0,10], y in [1,2,3])) do v
v[1]+v[2]
end
2×3 Array{Int64,2}:
1 2 3
11 12 13
You could use Iterators.product:
julia> map(t -> t[1]+t[2], Iterators.product([0,10], [1,2,3]))
2×3 Array{Int64,2}:
1 2 3
11 12 13
Iterators.product returns an iterator whose elements are tuples.
(It's a shame the anonymous function above couldn't be written (x,y) -> x+y)
I have a data frame x:
begin end
1 1 3
2 5 6
3 11 18
and a vector v <- c(1,2,5,9,10,11,17,20)
I'd like to find all values from vector that are elements of any of interval from data frame. So i would like to get a vector c(1,2,5,11,17). How is it possible?
To get row-wise values, use apply on MARGIN 1 with intersect
apply(df, 1, function(a) intersect(v, a[1]:a[2]))
#[[1]]
#[1] 1 2
#[[2]]
#[1] 5
#[[3]]
#[1] 11 17
OR unlist to get a vector
unlist(apply(df, 1, function(a) intersect(v, a[1]:a[2])))
#OR
intersect(v, unlist(apply(df, 1, function(a) a[1]:a[2]))) #as commented by akrun
#[1] 1 2 5 11 17
We can use Map to get the sequence between corresponding, begin/end values in a list, unlist the list and use intersect to get the elements common in both the vectors
intersect(unlist(Map(`:`, x$begin, x$end)), v)
#[1] 1 2 5 11 17
From R documentation:
sweep: Return an array obtained from an input array by sweeping out a summary
statistic.
For example, here is how I divide each row by its row sum:
> rs = rowSums(attitude)
> ratios = sweep(attitude, 1, rs, FUN="/")
> head(ratios)
rating complaints privileges learning raises critical advance
1 0.1191136 0.1412742 0.08310249 0.1080332 0.1689751 0.2548476 0.12465374
2 0.1518072 0.1542169 0.12289157 0.1301205 0.1518072 0.1759036 0.11325301
3 0.1454918 0.1434426 0.13934426 0.1413934 0.1557377 0.1762295 0.09836066
4 0.1568123 0.1619537 0.11568123 0.1208226 0.1388175 0.2159383 0.08997429
5 0.1680498 0.1618257 0.11618257 0.1369295 0.1473029 0.1721992 0.09751037
6 0.1310976 0.1676829 0.14939024 0.1341463 0.1646341 0.1493902 0.10365854
> rowSums(ratios) # check that ratios sum up to 1
[1] 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
My attempt in Julia:
x = rand(3, 4)
x[1, 1] = 10
x[2, 1] = 20
x[3, 1] = 30
rowsum = sum(x, 2)
rowsum_mat = repmat(rowsum, 1, size(x, 2))
x = x ./ rowsum_mat
This works but is clunky. Is there a more elegant and efficient way of doing this?
No need to use repmat — all of Julia's .-operators do "broadcasting" by default. This means it matches the dimensions of the two arguments and then expands any dimensions that have length 1 (the singleton dimensions) to match the other array. Since reductions keep the same dimensionality of the source array, they can be used directly with any dot-operator.
In your case, you can just use:
x ./ sum(x, 2)
since:
julia> x ./ rowsum_mat == x ./ rowsum
true
I had a function in R (onestep below) which took as an argument a vector v and returned a new vector v as output which was a function of the input vector. I then iterated this function niter times and kept the output vectors of each iteration (which are not all the same length and can occasionally also end up having length 0) in another function iterate as follows (minimal example) :
onestep = function (v) c(v,2*v)
iterate = function (v, niter) sapply(1:niter, function (iter) {v <<- onestep(v)
return(v) } )
Example :
v=c(1,2,3)
iterate(v,3)
[[1]]
[1] 1 2 3 2 4 6
[[2]]
[1] 1 2 3 2 4 6 2 4 6 4 8 12
[[3]]
[1] 1 2 3 2 4 6 2 4 6 4 8 12 2 4 6 4 8 12 4 8 12 8 16 24
I was wondering what would be a compact and idiomatic way to do such a recursive function that returns all the intermediate results in Julia? Any thoughts? (Apologies if this is trivial but I am new to Julia)
Not sure on the compact and idiomatic front, but this is how I'd do it
onestep(v) = [v 2*v]
function iterate(v, niter)
Results = Array(Array, niter)
Results[1] = onestep(v)
for idx = 2:niter
Results[idx] = onestep(Results[idx - 1])
end
Results
end
v = [1 2 3]
iterate(v, 3)
Here is another way that is a bit more concise and more truly recursive, as per your original question:
v = Array[[1, 2, 3]] ## create v as an array of one dimensional arrays
function iterate(v::Array{Array, 1}, niter::Int)
niter == 0 && return v[2:end]
push!(v, [v[end] ; 2v[end]])
niter -= 1
iterate(v, niter)
end
iterate(v, 3)