numpy - translate an 2 dimensional array with a different x and y? - python

Let's say there's an np array like this:
k = np.array([[13, 29],
[17, 18],
[19, 27]])
Now, I need to subtract 4 from column 1 and 8 from column 2 without looping with Numpy.
I tried k - 4 but it seems to subtract even from axis 1.

k - [4, 8]
Demo:
>>> >>> import numpy as np
>>> k = np.array([[13, 29],
[17, 18],
[19, 27]])
>>> k - [4, 8]
array([[ 9, 21],
[13, 10],
[15, 19]])

You can just index the column, row or whatever you want (guide by scipy here) and then subtract whatever you want from each element in that section with -=:
>>> a
array([[13, 29],
[17, 18],
[19, 27]])
>>> a[:,0] -= 4
>>> a
array([[ 9, 29],
[13, 18],
[15, 27]])
>>> a[:,1] -= 8
>>> a
array([[ 9, 21],
[13, 10],
[15, 19]])

Related

How does np.argmax(axis=0) work on 3D arrays?

I am stuck at, as to how does np.argmax(arr, axis=0) work? I know how np.argmax(axis=0) works on 2D arrays. But this 3D one has really confused me.
My Code:
arr = np.array([[[ 1, 2, 3],
[ 4, 5, 6],
[ 7, 8, 9],
[10, 11, 12]],
[[13, 14, 15],
[16, 17, 18],
[19, 20, 21],
[22, 23, 24]],
[[25, 26, 27],
[28, 29, 30],
[31, 32, 33],
[34, 35, 36]]])
Operation:
np.argmax(arr, axis = 0)
Output:
array([[2, 2, 2],
[2, 2, 2],
[2, 2, 2],
[2, 2, 2]], dtype=int64)
FYI - I do know how np.argmax(axis=0) works on 2D arrays. But this 3D one has really confused me.
You need to understand better what is axis=0 here. It can be interpreted as height level of rectangle. So your output shows different levels of that rectangle:
level 0 level 1 level 2
[ 1, 2, 3] [13, 14, 15] [16, 17, 18]
[ 4, 5, 6] [16, 17, 18] [19, 20, 21]
[ 7, 8, 9] [19, 20, 21] [22, 23, 24]
[10, 11, 12] [22, 23, 24] [25, 16, 27]
Then argmax describes indices of levels at which max values are attained. They are:
[16, 17, 18]
[19, 20, 21]
[22, 23, 24]
[25, 16, 27]
It's definitely the upmost level (number 2) for any of these cells
so argmax of every cell is assigned to 2.

add left and right portions of the array symmetrically - python

a = np.array([[[ 1, 11],
[ 3, 13],
[ 5, 15],
[ 7, 17],
[ 9, 19]],
[[ 2, 12],
[ 4, 14],
[ 6, 16],
[ 8, 18],
[10, 20]]])
I'm trying to add the left portion to the right portion of the array in a symmetrical way along the second dimension (so 1+9, 11+19, 3+7, 13+17 for the first sub array above).
I tried this
>>> middle = int(np.ceil(a.shape[1]/2))
>>> a[:,:middle-1,:] + a[:,middle:,:]
array([[[ 8, 28],
[12, 32]],
[[10, 30],
[14, 34]]], dtype=uint8)
which adds the left to the right but not symmetrically. This is what I'm hoping to get
array([[[10, 30],
[10, 30]],
[[12, 32],
[12, 32]]], dtype=uint8)
Looks like you may invert the array, add and cut to the a.shape[1]//2 middle
(a + a[:,::-1,:])[:, :a.shape[1]//2, :]
array([[[10, 30],
[10, 30]],
[[12, 32],
[12, 32]]])
A small modification to your code will work:
middle = int(np.ceil(a.shape[1]/2))
print(a[:,:middle-1,:] + a[:,:middle-1:-1,:])
The second addend is sliced differently here to reverse it. (Original was a[:,middle:,:])
Result:
[[[10 30]
[10 30]]
[[12 32]
[12 32]]]
You can either use backward slicing "[b:a:-1]"
i,j,k = a.shape
a[:,:j//2] + a[:,:(j-1)//2:-1]
# array([[[10, 30],
# [10, 30]],
#
# [[12, 32],
# [12, 32]]])
Or to avoid the slightly error prone computation of the backward limits you can use np.fliplr
half = np.s_[:,:a.shape[1]//2]
a[half] + np.fliplr(a)[half]
# array([[[10, 30],
# [10, 30]],
#
# [[12, 32],
# [12, 32]]])

How to subset a numpy array of different lengths

I have a numpy array and would like to subset the first two arrays of each element in an ndarray.
Here is an example array:
import numpy as np
a1 = np.array([[ 1, 2, 3],
[ 4, 5, 6]])
a2 = np.array([[ 7, 8, 9],
[10, 11, 12],
[13, 14, 15],
[16, 17, 18]])
a3 = np.array([[19, 20, 21],
[22, 23, 24],
[25, 26, 27]])
A = np.array([a1, a2, a3])
print("A =\n", A)
Which prints:
A =
[array([[ 1, 2, 3],
[ 4, 5, 6]])
array([[ 7, 8, 9],
[10, 11, 12],
[13, 14, 15],
[16, 17, 18]])
array([[19, 20, 21],
[22, 23, 24],
[25, 26, 27]])]
The desired result is as follows:
A =
[array([[ 1, 2, 3],
[ 4, 5, 6]])
array([[ 7, 8, 9],
[10, 11, 12]])
array([[19, 20, 21],
[22, 23, 24]])]
To print the equivalent object, you could do
print(np.array([a1[0:2], a2[0:2], a3[0:2]]))
But I want to directly get what is desired using A.
What is the correct way of doing this in numpy?
Edit: I would like to subset the array without looping. Alternative ways of structuring the arrays so that they can be directly indexed are okay too. Any numpy function to avoid looping is fair game.
a = [i[0:2] for i in A]
This will work!

How to add matrix and vector column-wise?

Consider the following:
>>> matrix = numpy.array([[1, 2, 3],
... [4, 5, 6],
... [7, 8, 9]])
>>> vector = numpy.array([10, 20, 30])
>>> matrix + vector
array([[11, 22, 33],
[14, 25, 36],
[17, 28, 39]])
This adds the vector and the matrix row-wise (i.e. each row being added the vector).
How to perform the same column-wise? The result should be
>>> ???
array([[11, 12, 13],
[24, 25, 26],
[37, 38, 39]])
I'm aware that I can use
>>> (matrix.T + vector).T
array([[11, 12, 13],
[24, 25, 26],
[37, 38, 39]])
However I have many such additions and using this double transposition will make the code quite unreadable. Is there a way to configure ndarrays such that they will perform addition along the first axis (instead of the last)?
Make the vector a column:
matrix + vector[:, None]

Slice list of lists without numpy

In Python, how could I slice my list of lists and get a sub list of lists without numpy?
For example, get a list of lists from A[1][1] to A[2][2] and store it in B:
A = [[1, 2, 3, 4 ],
[11, 12, 13, 14],
[21, 22, 23, 24],
[31, 32, 33, 34]]
B = [[12, 13],
[22, 23]]
You can slice A and its sublists:
In [1]: A = [[1, 2, 3, 4 ],
...: [11, 12, 13, 14],
...: [21, 22, 23, 24],
...: [31, 32, 33, 34]]
In [2]: B = [l[1:3] for l in A[1:3]]
In [3]: B
Out[3]: [[12, 13], [22, 23]]
You may also perform nested list slicing using map() function as:
B = map(lambda x: x[1:3], A[1:3])
# Value of B: [[12, 13], [22, 23]]
where A is the list mentioned in the question.

Categories