tf.ones_like(tensor) with a specific index set to 0 - python

I am trying to mimic tf.ones_like() where "Given a single tensor (tensor), this operation returns a tensor of the same type and shape as tensor with all elements set to 1." except I want to specify a certain column index to be set to 0. For example, I want the first column to be all 0
if Given tensor = [[1,2,3], [4,5,6]] then I would like to return [[0,1,1], [0,1,1]] if I specify the first column. Is there any way to do this with tensorflow operations?

IMHO, from Variable helper functions only the assign can be of any reasonable help in cases like this. If you would not choose to let numpy out, I can suggest this code:
t = np.array([[1,2,3],[4,5,6]])
v = tf.Variable(t)
t = np.ones_like(t)
t[:,0] = 0
sess = tf.Session()
print(sess.run(v.assign(t)))

Related

Array mean iteration

My question pertains to array iteration but is a bit more complicated. You see I have an array with a shape of (4, 50). What I want to do is find the mean of the arrays. I will show a simple explanation of what I mean
A = np.array([[10,5,3],[12,6,6],[9,8,7],[20,3,4]])
When this code is run, you get an array with a shape of (4,3). What I want is for the mean of each row to be found and returned.
Returned should be an array of ([[6],[8],[8],[9]]) with the same rows and naturally a column of 1.
Please explain the code and thought process behind it. Thank you very much.
Use the numpy.mean function. Parameter axis=1 means that the row-wise mean will be calculated. Parameter keepdims=True means that original array dimensions are kept.
import numpy as np
A = np.array([[10,5,3],[12,6,6],[9,8,7],[20,3,4]])
B = np.mean(A, axis=1, keepdims=True)
print(B)
# Output:
# [[6.]
# [8.]
# [8.]
# [9.]]
Use np.mean and list comprehension into a new array:
A = np.array([[10,5,3],[12,6,6], [9,8,7],[20,3,4]])
# Use .reshape() to get 4 rows by 1 column.
new_A = np.array([np.mean(row) for row in A]).reshape(-1, 1)
Output:
array([[6.], [8.], [8.], [9.]])

Subsetting a two dimensional tensor with a one dimensional tensor

I want to extract from each row of a two-dimensional tensor the column that is stored in another one dimensional tensor.
import torch
test_tensor = tensor([1,-2,3], [-2,7,4]).float()
select_tensor = tensor([1,2])
So in this particular example I would like to get the element in position 1 for the first row (so -2) and the element in position 2 for the second row (so 4).
I tried:
test_tensor[:, select_tensor]
But this selects the elements at position 1 and 2 for each row. I suspect it might be something very simple that I am missing.
You can use torch.gather
import torch
test_tensor = torch.tensor([[1,-2,3], [-2,7,4]]).float()
select_tensor = torch.tensor([1,2], dtype=torch.int64).view(-1,1) # number of dimension should match with the test tensor.
final_tensor = torch.gather(test_tensor, 1, select_tensor)
final_tensor
output
tensor([[-2.],
[ 4.]])
or, use torch.view to flatten the output tensor: final_tensor.view(-1) will give you tensor([-2., 4.])
If you're looking for a solution with indexing, you need to index on axis=0 as well, you could do that with torch.arange:
>>> test_tensor = torch.tensor([[1,-2,3], [-2,7,4]])
>>> select_tensor = torch.tensor([1,2])
>>> test_tensor[torch.arange(len(select_tensor)), select_tensor]
tensor([-2, 4])

numpy.take range of array elements Python

I have an array of integers.
data = [10,20,30,40,50,60,70,80,90,100]
I want to extract a range of integers from the array and get a smaller array.
data_extracted = [20,30,40]
I tried numpy.take.
data = [10,20,30,40,50,60,70,80,90,100]
start = 1 # index of starting data entry (20)
end = 3 # index of ending data entry (40)
data_extracted = np.take(data,[start:end])
I get a syntax error pointing to the : in numpy.take.
Is there a better way to use numpy.take to store part of an array in a separate array?
You can directly slice the list.
import numpy as np
data = [10,20,30,40,50,60,70,80,90,100]
data_extracted = np.array(data[1:4])
Also, you do not need to use numpy.array, you could just store the data in another list:
data_extracted = data[1:4]
If you want to use numpy.take, you have to pass it a list of the desired indices as second argument:
import numpy as np
data = [10,20,30,40,50,60,70,80,90,100]
data_extracted = np.take(data, [1, 2, 3])
I do not think numpy.take is needed for this application though.
You ought to just use a slice to get a range of indices, there is no need for numpy.take, which is intended as a shortcut for fancy indexing.
data_extracted = data[1:4]
As others have mentioned, you can use fancy indexing in this case. However, if you need to use np.take because e.g. the axis you're slicing over is variable, you might try:
axis=0
data.take(range(1,4), axis=axis)
Note: this might be slower than:
data_extracted = data[1:4]

Cleanest way to replace np.array value with np.nan by user defined index

One question about mask 2-d np.array data.
For example:
one 2-d np.array value in the shape of 20 x 20.
An index t = [(1,2),(3,4),(5,7),(12,13)]
How to mask the 2-d array value by the (y,x) in index?
Usually, replacing with np.nan are based on the specific value like y[y==7] = np.nan
On my example, I want to replace the value specific location with np.nan.
For now, I can do it by:
Creating a new array value_mask in the shape of 20 x 20
Loop the value and testify the location by (i,j) == t[k]
If True, value_mask[i,j] = value[i,j] ; In verse, value_mask[i,j] = np.nan
My method was too bulky especially for hugh data(3 levels of loops).
Are there some efficiency method to achieve that? Any advice would be appreciate.
You are nearly there.
You can pass arrays of indices to arrays. You probably know this with 1D-arrays.
With a 2D-array you need to pass the array a tuple of lists (one tuple for each axis; one element in the lists (which have to be of equal length) for each array-element you want to chose). You have a list of tuples. So you have just to "transpose" it.
t1 = zip(*t)
gives you the right shape of your index array; which you can now use as index for any assignment, for example: value[t1] = np.NaN
(There are lots of nice explanation of this trick (with zip and *) in python tutorials, if you don't know it yet.)
You can use np.logical_and
arr = np.zeros((20,20))
You can select by location, this is just an example location.
arr[4:8,4:8] = 1
You can create a mask the same shape as arr
mask = np.ones((20,20)).astype(bool)
Then you can use the np.logical_and.
mask = np.logical_and(mask, arr == 1)
And finally, you can replace the 1s with the np.nan
arr[mask] = np.nan

Selection of data in a single dimension (which can vary) in a multi-dimensional array

Say I have a multi-dimensional array of shape (80,80,17,5,27), where 27 (the slice axis) can be in the third, fourth, or fifth dimension.
I would like to select a subset of data within the slice axis; as an example:
slice_axis = N.shape(data).index(27) # slice_axis=4 for data listed above
data_new = data[:,:,:,:,0:tot_slices/2] # where this selection location depends on the slice axis
Alternatively, if the data shape looks like this: (80,80,27,17,5):
Then slice_axis=2 and data_new = data[:,:,0:tot_slices/2,:,:]
Is there a quick way to do this, preferably without having to transpose the data?
If I understand your question correctly, the following should work:
slice_idx = N.shape(data).index(27)
slices = [ slice( 0, None, None),]*4
slices.insert( slice_idx, slice( 0, tot_slices/2, None))
data_new = data.__getitem__(slices)
The solution that I came up with before mdurant answered it is as follows:
selected_axis = N.shape(data).index(27)
# delete 1 dynamic to create an even split of the data (because 27 is an odd number)
data = N.delete(data,N.ceil(27/2), axis=selected_axis)
(data_base,data_activation) = N.split(data,2,axis=selected_axis)

Categories

Resources