I'm trying to understand the following code.
content_array[:, :, :, 0] -= 103.939
content_array[:, :, :, 1] -= 116.779
content_array[:, :, :, 2] -= 123.68
content_array = content_array[:, :, :, ::-1]
style_array[:, :, :, 0] -= 103.939
style_array[:, :, :, 1] -= 116.779
style_array[:, :, :, 2] -= 123.68
style_array = style_array[:, :, :, ::-1]
content_array and style_array are arrays with dimensions of
(1, 512, 512, 3) respectively.
What i don't really understand is the indexing([:, :, :, 0], [:, :, :, 1], [:, :, :, 2]). Does this means we are indexing each dimension? and why do we use ':'?
One of numpy's most interesting indexing features, is the ability to index slices. Slices are subarrays in a given dimensions, they are written in the form of i:j:k where i is the starting index, j the ending (not included), and k the step. Specifying all 3 parameters would be tedious most of the time, that's why they all have default values. i=0, j=n where n is the length of the array, k=1. Therefore selecting all the elements along a dimension would come down to writting array[::] for which a syntactic sugar is array[:].
Therefore content_array[:, :, :, 0] is an array of dimension (1, 512, 512). And writing content_array[:, :, :, 0] -= 103.939 means set all the values of the array taken by selecting all the elements such that they have index 0 on last dimension, and decrement all these elements by 103.939.
I would recommend that you read https://docs.scipy.org/doc/numpy/reference/arrays.indexing.html.
Related
I want to sample len(valid_frame_id_ls) frame from data by fancy indexing for numpy arrary. But I received an error message when i run code1. I don't know why the shape of data[n, :, valid_frame_id_ls, :, :] is not equal to the shape of new_data[n, :, :len(valid_frame_id_ls), :, :].Can anyone help me solve this bug. help...
I modify my code and write in code2 block. I did't receive any error message when i run code2. I don't know why code2 is correct.
code1:
data = np.random.random((2, 3, 50, 25, 1))
N, C, T, V, M = data.shape
new_data = np.zeros((N, C, T, V, M))
valid_frame_id_ls = [2, 3, 4, 5, 6]
for n in range(N):
new_data[n, :, :len(valid_frame_id_ls), :, :] = data[n, :, valid_frame_id_ls, :, :]
# code1 error message:
new_data[n, :, :len(valid_frame_id_ls), :, :] = data[n, :, valid_frame_id_ls, :, :]
ValueError: could not broadcast input array from shape (5,3,25,1) into shape (3,5,25,1)
code2:
data = np.random.random((2, 3, 50, 25, 1))
N, C, T, V, M = data.shape
new_data = np.zeros((N, C, T, V, M))
valid_frame_id_ls = [2, 3, 4, 5, 11]
for n in range(N):
new_data[n][:, :len(valid_frame_id_ls), :, :] = data[n][ :, valid_frame_id_ls, :, :]
https://numpy.org/doc/stable/reference/arrays.indexing.html#combining-advanced-and-basic-indexing
As described in this section of the docs, putting a slice in the middle of 'advanced' indexing results in an unexpected rearrangement of dimensions. Your size 5 dimension has been placed first, and the other dimensions after.
This has come up occasionally on SO as well. With a scalar n this really shouldn't be happening, but apparently the issue occurs deep in the indexing, and isn't easily corrected.
data[n][ :, valid_frame_id_ls, :, :]
breaks up the indexing, so the first ':' is no longer in the middle.
Another fix is to replace the slice with an equivalent array. Now both sides will have the same dimensions.
new_data[n, :, np.arange(len(valid_frame_id_ls)), :, :] = data[n, :, valid_frame_id_ls, :, :]
Though in this case I don't think you need to iterate on N at all:
new_data[:,:,:len(valid_frame_id_ls),:,:] = data[:,:, valid_frame_id_ls, :,:]
I have N, 2x4 arrays stored in a (2x4xN) array J. I am trying to calculate the pseudoinverse for each of the N, 2x4 arrays, and save the pseudoinverses to a (N x 4 x 2) array J_pinv.
What I'm currently doing:
J_pinvs = np.zeros((N, 4, 2))
for i in range(N):
J_pinvs[i, :, :] = np.transpose(J[:, :, i]) # np.linalg.inv(J[:, :, i] # J[:, :, i].transpose())
This works but I would like to speed up the compute time as this will be running in a layer of a neural network so I would like to make it as fast as possible.
What I've tried:
J_pinvs = np.zeros((N, 4, 2))
J_pinvs2[:, :, :] = np.transpose(J[:, :, :]) # np.linalg.inv(J[:, :, :] # J[:, :, :].transpose())
Generates the error:
<ipython-input-87-d8ee1ba2ae5e> in <module>
1 J_pinvs2 = np.zeros((4, 2, 3))
----> 2 J_pinvs2[:, :, :] = np.transpose(J[:, :, :]) # np.linalg.inv(J[:, :, :] # J[:, :, :].transpose())
ValueError: matmul: Input operand 1 has a mismatch in its core dimension 0, with gufunc signature (n?,k),(k,m?)->(n?,m?) (size 4 is different from 3)
Is there a way to do this with slicing so that I don't need to use an iterator? I'm having trouble finding anything online. Any help/suggestions would be appretiated!
Thanks,
JM
I think you need to specify how to transpose a 3-D array:
np.linalg.inv(a # a.transpose(0,2,1))
will work. As oppose to
# sample data
a = np.arange(24).reshape(-1,2,4)
a.shape
# (3, 2, 4)
a.transpose().shape
# (4, 2, 3)
and
a # a.transpose()
will not work.
Finally, the whole script should be:
a.transpose(0,2,1) # np.linalg.inv(a # a.transpose(0,2,1))
I would like to create an index in the form of
[:, :, :, 0, :, :, :, :]
where the position of 0 is determined by a variable, say axis to slice a NumPy array. Obviously there are two special cases that are easy to treat:
axis = 0 would be equivalent to [0, ...]
axis = -1 would be equivalent to [..., 0]
But I wonder how this can be done for any axis value?
You can create a tuple and use slice(None) in place of ::
def custom_index(arr, position, index):
idx = [slice(None)] * len(arr.shape)
idx[position] = index
return arr[tuple(idx)]
Quick test:
mat = np.random.random((5, 3))
assert np.all(mat[2, :] == custom_index(mat, 0, 2)) # mat[(2, slice(None))]
assert np.all(mat[:, 2] == custom_index(mat, 1, 2)) # mat[(slice(None), 2))]
EDIT: as pointed out in the comment, the proper way is np.take
Given X is a Numpy Array X.shape =(1, 96, 96, 3), Basically an Image read from CV2 . I am looking for simpler articulation of a augment operation.
Could you please explain what the following lines of code does
b=X[:, ::-1, :, :]
c=X[:, ::-1, ::-1, :]
d=X[:, :, ::-1, :]
X[::-1] indexing applies: indices of X from first to last in steps of -1.
b=X[:, ::-1, :, :] - Reverse image up/down.
c=X[:, ::-1, ::-1, :] - Reverse image up/down and left/right.
d=X[:, :, ::-1, :] - Reverse image left/right.
Remark:
:: is not an operator, it's actually two : operators one after the other.
X[::-1] is the same as X[ : : -1].
Refer to Indexing documentation.
The basic slice syntax is i:j:k where i is the starting index, j is the stopping index, and k is the step.
If i is not given it defaults to 0
If j is not given it defaults to n
Writing [: : -1], omits i and j, and sets k to -1.
The syntax means: "from index 0, take all elements, with step -1", that gives all elements in reverse order (all elements along this axis).
Example:
import cv2
import numpy as np
# Build input:
im = cv2.imread('chelsea.png')
im = cv2.resize(im, (96, 96))
X = np.empty((1, im.shape[0], im.shape[1], im.shape[2])).astype(np.uint8)
X[0, :, :, :] = im
b = X[:, ::-1, :, :]
c = X[:, ::-1, ::-1, :]
d = X[:, :, ::-1, :]
Result:
im:
b:
c:
d:
Note:
I kind of ignored the fist index because the dimension is 1.
In case of multiple frames, it's common for the fist index to apply the number of frames.
I have a Tensorflow tensor A of size (64, 2, 82, 1), and I want to replace its (:, :, 80:82, :) part with the corresponding part of the tensor B (also (64, 2, 82, 1) size).
How would I do that?
P.S.: To be precise, I mean the operation that would look like this in the numpy:
A[:, :, 80:82, :] = B[:, :, 80:82, :]
the following code might help you to get some idea,
a = tf.constant([[11,0,13,14],
[21,22,23,0]])
condition = tf.equal(a, 0)
case_true = tf.reshape(tf.multiply(tf.ones([8], tf.int32), -9999), [2, 4])
case_false = a
a_m = tf.where(condition, case_true, case_false)
sess = tf.Session()
sess.run(a_m)
here i am accessing individual element of a tensor!
tf.assign should work: (not tested)
tf.assign(A[:, :, 80:82, :], B[:, :, 80:82, :])