Numpy: constructing a 3D array from a 1D array - arrays

Assume a 1D array A is given. Is there an easy way to construct a 3D array B, such that B[i,j,k] = A[k] for all i,j,k? You can assume that the shape of B is prescribed, and that B.shape[2] = A.shape[0].

>>> k = 4
>>> a = np.arange(k)
>>> j = 3
>>> i = 2
>>> np.tile(a,j*i).reshape((i,j,k))
array([[[0, 1, 2, 3],
[0, 1, 2, 3],
[0, 1, 2, 3]],
[[0, 1, 2, 3],
[0, 1, 2, 3],
[0, 1, 2, 3]]]

Another easy way to do this is simple assignment -- broadcasting will automatically do the right thing:
i = 2
j = 3
k = 4
a = numpy.arange(k)
b = numpy.empty((i, j, k))
b[:] = a
print b
prints
[[[ 0. 1. 2. 3.]
[ 0. 1. 2. 3.]
[ 0. 1. 2. 3.]]
[[ 0. 1. 2. 3.]
[ 0. 1. 2. 3.]
[ 0. 1. 2. 3.]]]

for k,v in enumerate(A): B[:,:,k] = v

Related

Remove elements from an array into another array (Ruby)

I'm new here and new to coding and I can use some help with a problem I'm trying to solve.
I'm trying to remove all integers that are less than 5 from array
a = [1, 2, 3, 4, 5, 6] and put them into a new array b = [], and then print out the b array.
I've done many Google searches but I can't find anything that helps.
I'm starting to think this is not possible.
Please help!
Thanks
a = [1, 2, 3, 4, 5, 6]
b, a = a.partition { |i| i < 5 }
#=> [[1, 2, 3, 4], [5, 6]]
b #=> [1, 2, 3, 4]
a #=> [5, 6]
See Enumerable#partition.
a = [1, 2, 3, 4, 5, 6]
b = a.select { |i| i < 5 } # [1, 2, 3, 4]
a = a - b # [5, 6]
To actually remove elements from a while putting them in an existing array b, you could use reject!:
a = [1, 2, 3, 4, 5, 6]
b = []
a.reject! { |i| b << i if i < 5 }
a #=> [5, 6]
b #=> [1, 2, 3, 4]
If i < 5 evaluates to true, b << i puts that element in b and returns a truthy result which causes reject! to remove it from a.
Likewise, if i < 5 evaluates to false, b << i is skipped, the block returns a falsy result and that element remains in a.

Replace elements of numpy array based on first occurrence of a particular value

Suppose there's a numpy 2D array as follows:
>>> x = np.array([[4,2,3,1,1], [1,0,3,2,1], [1,4,4,3,4]])
>>> x
array([[4, 2, 3, 1, 1],
[1, 0, 3, 2, 1],
[1, 4, 4, 3, 4]])
My objective is to - find the first occurrence of value 4 in each row, and set the rest of the elements (including that element) in that row to 0. Hence, after this operation, the transformed array should look like:
>>> x_new
array([[0, 0, 0, 0, 0],
[1, 0, 3, 2, 1],
[1, 0, 0, 0, 0]])
What is the pythonic and optimized way of doing this? I tried with a combination of np.argmax() and np.take() but was unable to achieve the end objective.
You can do it using a cumulative sum across the columns (i.e. axis=1) and boolean indexing:
n = 4
idx = np.cumsum(x == n, axis=1) > 0
x[idx] = 0
or maybe a better way is to do a cumulative (logical) or:
idx = np.logical_or.accumulate(x == n, axis=1)

Ruby: How to find to similarity in two arrays

I am trying to find the common elements in two arrays.
pairs = Array.new
a = exchange_one.get_symbols
b = exchange_two.get_symbols
c = a+b
c.uniq{|pair| pairs << pair}
I am combining the two arrays using +
Then I am calling uniq to remove the duplicate, but passing it to a block so the found duplicates can be added to an array before they are deleted.
For some reason the array pairs is just the entire c array.
What is the correct way to find array similarities.
If your goal is simply to determine which elements are the same between two arrays, you can use the intersection operator Array#&.
a = exchange_one.get_symbols
b = exchange_two.get_symbols
intersection = a & b
First understand what are you doing and what you want.
For eg.
a = 15.times.map { rand 6 }
#=> [1, 0, 5, 3, 1, 3, 4, 1, 3, 2, 1, 2, 4, 2, 3]
b = 15.times.map { rand 6 }
#=> [3, 3, 3, 1, 3, 1, 3, 1, 5, 1, 4, 2, 0, 0, 4]
Now what are you doing
c = a + b
#=> [1, 0, 5, 3, 1, 3, 4, 1, 3, 2, 1, 2, 4, 2, 3, 3, 3, 3, 1, 3, 1, 3, 1, 5, 1, 4, 2, 0, 0, 4]
c - only combine arrays irrespective of content hence get all values.
Now
pairs = Array.new
c.uniq{|pair| pairs << pair}
Here uniq is just act as a iterator means if you check 'pair' then it iterate all the values of 'c' and insert those values in 'pairs' array.
check this
c.uniq{|pair| puts pair}
Thats why you are getting all values within 'pairs' array.
The best way to find similarity in arrays is (a&b), but you can make changes in your code as follow to achieve it.
pairs = (arr1+arr2).uniq
OR
pairs = arr1 & arr2 #best and efficient way.
Suppose:
arr1 = 15.times.map { rand 6 }
#=> [1, 0, 4, 0, 2, 3, 1, 0, 2, 4, 4, 1, 3, 1, 1]
arr2 = 15.times.map { rand 6 }
#=> [5, 5, 4, 1, 5, 1, 5, 0, 4, 0, 2, 0, 4, 5, 0]
arr1 contains 5 1s and arr2 contains 2 1s. If, by "common elements" you wish to report that both arrays contain [5, 2].min #=> 2 1s, and similar counts for the other elements that appear in either array, you can do the following:
h1 = count(arr1)
#=> {1=>5, 0=>3, 4=>3, 2=>2, 3=>2}
h2 = count(arr2)
#=> {5=>5, 4=>3, 1=>2, 0=>4, 2=>1}
(h1.keys | h2.keys).each_with_object({}) { |k,h| h[k] = [h1[k], h2[k]].min }
#=> {1=>2, 0=>3, 4=>3, 2=>1, 3=>0, 5=>0}
def count(arr)
arr.each_with_object(Hash.new(0)) { |n,h| h[n] += 1 }
end

Divide array into subarray

I want to create two sub-arrays from this array:
a = [0, 1, 2, 3, 4, 5, 6]
This array will not always contain the same number of elements because it depends on the user input.
For example, in some occasions it'll be:
a = [0, 5]
or:
a = [5, 6, 4]
I want to divide the array into two subarrays. The first one will contain numbers from 1 to 4 (inclusive) and the second one will contain 0, 5 and 6.
In the first example, it will be:
a = [0, 1, 2, 3, 4, 5, 6]
sub_array1 = [1, 2, 3, 4]
sub_array2 = [0, 5, 6]
In the second:
a = [0, 5]
sub_array1 = []
sub_array2 = [5]
In the third:
a = [5, 6, 4]
sub_array1 = [4]
sub_array2 = [5, 6]
and so on, depending on the user input.
How can I do this?
First thing that comes to mind is Enumerable#partition.
sub_array1, sub_array2 = [0,1,2,3,4,5,6].partition {|x| (1..4).include? x }
=> [[1,2,3,4], [0,5,6]]
if you have two conditions (I mean if 0,5,6 are an actual condition and not the excluded set) I think that a double iteration wouldn't hurt
a = [0,1,2,3,4,5,6]
sub_array1 = a.select { |x| (1..4).include? x }
sub_array2 = a.select { |x| [0,5,6].include? x }
You can try something like this:
[0,1,2,3,4,5,6].group_by{|x| [0,5,6].include? x}
The result will be a hash:
{true=>[0, 5, 6], false=>[1, 2, 3, 4]}
In the second case:
[0,5].group_by{|x| [0,5,6].include? x}
The result will be:
{true=>[0, 5]}

Fancy array access in Matlab

In Python numpy it is possible to use arrays of indexes, as in (taken from the tutorial):
data = array([[ 0, 1, 2, 3],
[ 4, 5, 6, 7],
[ 8, 9, 10, 11]])
i = array( [ [0,1], # indices for the first dim of data
[1,2] ] )
j = array( [ [2,1], # indices for the second dim
[3,3] ] )
Now, the invocation
data[i,j]
returns the array
array([[ 2, 5],
[ 7, 11]])
How can I get the same in Matlab?
I think you will have to use linear indexing which you'll get from the sub2ind function like this:
ind = sub2ind(size(data), I,J)
example:
data =[ 0, 1, 2, 3
4, 5, 6, 7
8, 9, 10, 11]
i = [0,1;
1,2];
j = [2,1;
3,3]
ind = sub2ind(size(data), i+1,j+1);
data(ind)
ans =
2 5
7 11
notice that I went i+1 and j+1, this is because unlike Python which starts indexing at 0, Matlab starts indexing from 1.

Resources