how to convert a (2,2) matrix to a (4,4) matrix - python

I am trying to double the size of a matrix without changing the values. Is there any dedicated function to do that? Here, I need to convert the matrix a to matrix b.
a = np.array([[1,2],
[3,4]])
b = np.array([[1,1,2,2],
[1,1,2,2],
[3,3,4,4],
[3,3,4,4]])

You can repeat on both axes:
a = np.array([[1, 2],
[3, 4]])
b =np.repeat(np.repeat(a, 2, axis=0), 2, axis=1)
Output:
array([[1, 1, 2, 2],
[1, 1, 2, 2],
[3, 3, 4, 4],
[3, 3, 4, 4]])

Related

How to get indices of N minimum values per row in a NumPy matrix with Python?

I have the following NumPy matrix:
m = np.array([[1, 2, 3, 4],
[10, 5, 3, 4],
[12, 8, 1, 2],
[7, 0, 2, 4]])
Now, I need the indices of N (say, N=2) lowest values of each row in this matrix . So with the example above, I expect the following output:
[[0, 1],
[2, 3],
[3, 2],
[1, 2]]
where the rows of the output matrix correspond to the respective rows of the original, and the elements of the rows of the output matrix are the indices of the N lowest values in the corresponding original rows (preferably in ascending order by values in the original matrix). How could I do it in NumPy?
You could either use a simple loop-approach (not recommended) or you use np.argpartition:
In [13]: np.argpartition(m, 2)[:, :2]
Out[13]:
array([[0, 1],
[2, 3],
[2, 3],
[1, 2]])
You could use np.argsort on your array and then slice the array with the amount of N lowest/highest values.
np.argsort(m, axis=1)[:, :2]
array([[0, 1],
[2, 3],
[2, 3],
[1, 2]], dtype=int64)
Try this;
import numpy as np
m = np.array([[1, 2, 3, 4],
[10, 5, 3, 4],
[12, 8, 1, 2],
[7, 0, 2, 4]])
for arr in m:
print(arr.argsort()[:2])

Element-wise multiply of multiple numpy 2d arrays

To simplify my question, let's say I have these arrays:
a = np.array([[1, 2, 3], [4, 5, 6]])
b = np.array([[2, 2, 2], [3, 3, 3]])
c = np.array([[1, 1, 3], [4, 1, 6]])
I would like to use element-wise multiplication on them so the result will be:
array([[ 2, 4, 18],
[ 48, 15, 108]])
I know I can do a*b*c, but that won't work if I have many 2d arrays or if I don't know the number of arrays. I am also aware of numpy.multiply but that works for only 2 arrays.
Use stack and prod.
stack will create an array which can be reduced by prod along an axis.
import numpy as np
a = np.array([[1, 2, 3], [4, 5, 6]])
b = np.array([[2, 2, 2], [3, 3, 3]])
c = np.array([[1, 1, 3], [4, 1, 6]])
unknown_length_list_of_arrays = [a, b, c]
d1 = a * b * c
stacked = np.stack(unknown_length_list_of_arrays)
d2 = np.prod(stacked, axis=0)
np.testing.assert_equal(d1, d2)

How can I create the following 4*4 Matrix from a 2*2 Matrix in Python?

a = np.array([[1,2],[3,4]])
b = np.array([[1,2,1,2],[3,4,3,4],[1,2,1,2],[3,4,3,4]])
I want to convert a to b here. How can I do this?
Thanks in advance
For those curious
Even though OP figured this out already: Here's how this can be achieve very easily
a = np.array([[1, 2], [3, 4]])
np.tile(a, (2, 2)) # (2, 2) = extend columns by 2 and rows by 2
>>> array([[1, 2, 1, 2],
[3, 4, 3, 4],
[1, 2, 1, 2],
[3, 4, 3, 4]])
np.tile(a, 2) # 2 = extend columns by 2
>>> array([[1, 2, 1, 2],
[3, 4, 3, 4]])
I wanted to comment on Bobs Burgers post, but don't have enough reputation. I was playing with np.repeat, and that wasn't quite getting me there. The closest I achieved was:
>>> import numpy as np
>>> a = np.array([[1,2],[3,4]])
array([[1, 2],
[3, 4]])
>>> a.repeat(2, axis=0).repeat(2, axis=1)
array([[1, 1, 2, 2],
[1, 1, 2, 2],
[3, 3, 4, 4],
[3, 3, 4, 4]])
I like the tile answer, but this might be useful for people looking for something slightly different.

How can I add a column to a numpy array

How can I add a column containing only "1" to the beginning of a second numpy array.
X = np.array([1, 2], [3, 4], [5, 6])
I want to have X become
[[1,1,2], [1,3,4],[1,5,6]]
You can use the np.insert
new_x = np.insert(x, 0, 1, axis=1)
You can use the np.append method to add your array at the right of a column of 1 values
x = np.array([[1, 2], [3, 4], [5, 6]])
ones = np.array([[1]] * len(x))
new_x = np.append(ones, x, axis=1)
Both will give you the expected result
[[1 1 2]
[1 3 4]
[1 5 6]]
Try this:
>>> X = np.array([[1, 2], [3, 4], [5, 6]])
>>> X
array([[1, 2],
[3, 4],
[5, 6]])
>>> np.insert(X, 0, 1, axis=1)
array([[1, 1, 2],
[1, 3, 4],
[1, 5, 6]])
Since a new array is going to be created in any event, it is just sometimes easier to do so from the beginning. Since you want a column of 1's at the beginning, then you can use builtin functions and the input arrays existing structure and dtype.
a = np.arange(6).reshape(3,2) # input array
z = np.ones((a.shape[0], 3), dtype=a.dtype) # use the row shape and your desired columns
z[:, 1:] = a # place the old array into the new array
z
array([[1, 0, 1],
[1, 2, 3],
[1, 4, 5]])
numpy.insert() will do the trick.
X = np.array([[1, 2], [3, 4], [5, 6]])
np.insert(X,0,[1,2,3],axis=1)
The Output will be:
array([[1, 1, 2],
[2, 3, 4],
[3, 5, 6]])
Note that the second argument is the index before which you want to insert. And the axis = 1 indicates that you want to insert as a column without flattening the array.
For reference:
numpy.insert()

Indexing numpy array with index array of lower dim yields array of higher dim than both

a = np.zeros((5,4,3))
v = np.ones((5, 4), dtype=int)
data = a[v]
shp = data.shape
This code gives shp==(5,4,4,3)
I don't understand why. How can a larger array be output? makes no sense to me and would love an explanation.
This is known as advanced indexing. Advanced indexing allows you to select arbitrary elements in the input array based on an N-dimensional index.
Let's use another example to make it clearer:
a = np.random.randint(1, 5, (5,4,3))
v = np.ones((5, 4), dtype=int)
Say in this case a is:
array([[[2, 1, 1],
[3, 4, 4],
[4, 3, 2],
[2, 2, 2]],
[[4, 4, 1],
[3, 3, 4],
[3, 4, 2],
[1, 3, 1]],
[[3, 1, 3],
[4, 3, 1],
[2, 1, 4],
[1, 2, 2]],
...
By indexing with an array of np.ones:
print(v)
array([[1, 1, 1, 1],
[1, 1, 1, 1],
[1, 1, 1, 1],
[1, 1, 1, 1],
[1, 1, 1, 1]])
You will simply be indexing a with 1 along the first axis as many times as v. Putting it in another way, when you do:
a[1]
[[4, 4, 1],
[3, 3, 4],
[3, 4, 2],
[1, 3, 1]]
You're indexing along the first axis, as no indexing is specified along the additional axes. It is the same as doing a[1, ...], i.e taking a full slice along the remaining axes. Hence by indexing with a 2D array of ones, you will have the above 2D array (5, 4) times stacked together, resulting in an ndarray of shape (5, 4, 4, 3). Or in other words, a[1], of shape (4,3), stacked 5*4=20 times.
Hence, in this case you'd be getting:
array([[[[4, 4, 1],
[3, 3, 4],
[3, 4, 2],
[1, 3, 1]],
[[4, 4, 1],
[3, 3, 4],
[3, 4, 2],
[1, 3, 1]],
...
the value of v is:
[[1 1 1 1]
[1 1 1 1]
[1 1 1 1]
[1 1 1 1]
[1 1 1 1]]
every single 1 indexes a complete "row" in a, but every "element" in said "row" is a matrix. so every "row" in v indexes a "row" of "matrix"es in a.
(does this make any sense to you..?)
so you get 5 * 4 1s, each is a 4*3 "matrix".
if instead of zeroes you define a as a = np.arange(5*4*3).reshape((5, 4, 3))
it might be easier to understand, because you get to see which parts of a are being chosen:
import numpy as np
a = np.arange(5*4*3).reshape((5, 4, 3))
v = np.ones((5,4), dtype=int)
data = a[v]
print(data)
(output is pretty long, I don't want to paste it here)

Categories

Resources