Failed to change one value in numpy matrix - python

When using matrix in numpy, I want to change the value of one element in a matrix using the index, but the result I got is strange.
How can I change one value in indexing method?
arr = np.array([[1, 2, 3, 4], [5, 6, 7, 8]])
mat1 = np.mat(arr)
mat1[1][0] = 3
print(arr)
[[1 2 3 4]
[3 3 3 3]]

Do the following change:
mat1[1][0] = 3 -> mat1[1,0] = 3

Related

Appending contents of 1D numpy array to another 2D numpy array

I have three numpy arrays. The shape of the first is (413, 2), the shape of the second is (176, 2), and the shape of the third is (589,). If you'll notice, 413 + 176 = 589. What I want to accomplish is to use the 589 values of the third np array and make the first two arrays of shapes (413, 3) and (176, 3) respectively.
So, what I want is to take the values in the third np array and append them to the columns of the first and second np arrays. I can do the logic for applying to the first and then using the offset of the length of the first to continue appending to the second with the correct values. I suppose I could also combine np arrays 1 and 2, they are separated for a reason though because of my data preprocessing.
To put it visually if that helps, what I have is like this:
Array 1:
[[1 2]
[3 4]
[4 5]]
Array 2:
[[6 7]
[8 9]
[10 11]]
Array 3:
[1 2 3 4 5 6]
And what I want to have is:
Array 1:
[[1 2 1]
[3 4 2]
[4 5 3]]
Array 2:
[[6 7 4]
[8 9 5]
[10 11 6]]
I've tried using np.append, np.concatenate, and np.vstack but have not been able to achieve what I am looking for. I am relatively new to using numpy, and Python in general, so I imagine I am just using these tools incorrectly.
Many thanks for any help that can be offered! This is my first time asking a question here so if I did anything wrong or left anything out please let me know.
Split the third array using the length of array1, then horizontally stack them. You need to use either np.newaxis or array.reshape to change the dimensionality of the slice of array3.
import numpy as np
array1 = np.array(
[[1, 2],
[3, 4],
[4, 5]]
)
array2 = np.array(
[[6, 7],
[8, 9],
[10, 11]]
)
array3 = np.array([1, 2, 3, 4, 5, 6])
array13 = np.hstack([array1, array3[:len(array1), np.newaxis]])
array23 = np.hstack([array1, array3[len(array1):, np.newaxis]])
Outputs:
array13
array([[1, 2, 4],
[3, 4, 5],
[4, 5, 6]])
array23
array([[ 6, 7, 4],
[ 8, 9, 5],
[10, 11, 6]])

How can I append two arrays, but have the second array in wide format? Python

If I have two arrays in python:
Array 1 =
[[1 2]
[3 4]]
Array 2 =
[[5 6]]
How can I use .append or .extend to create an array, such that:
Array 3:
[[1 2 5 6]
[3 4 5 6]]
Assuming you have numpy arrays, you can broadcast the second array to the shape of the first, and concatenate along the second axis with:
array1 = np.array([[1,2],[3,4]])
array2 = np.array([5,6])
np.c_[array1, np.broadcast_to(array2, array1.shape)]
array([[1, 2, 5, 6],
[3, 4, 5, 6]])
You can append the second array to the first one using np.append with axis=1.
array1 = np.array([[1,2],[3,4]])
array2 = np.array([[5,6]])
Make sure the shape match while appending, use broadcast_to to help with this
array3 = np.append(array1, np.broadcast_to(array2,array1.shape), axis=1)
[[1 2 5 6]
[3 4 5 6]]

'Tensor' object does not support item assignment while need to slice and then do assignmnet in tensor array

I want to find part of a tensor and then assign a constant number to that but I received this error.
It seems that the assignment to a tensor is not allowed in tensorflow. with that in mind, anyone has any idea how can I accomplish this one?
So for example if the tensor is like this:
tf_a2 = tf.Variable(([[2, 5, 1, 4, 3],
[1, 6, 4, 2, 3],
[0, 0, 0, 6, 6],
[2, 1, 1, 3, 3],
[4, 4, 1, 2, 3]]))
I want to find the elements per row in which they have the same value then I replace any element with N except the first element from left.
For example in the example above, in row=3, three elements =0, so
I kept the most left one the same as it is and then replace the right elements with the same value with N. in the same row there are two element with 6 value,I kept the most left element and replce all elements after that with the same value with N.
In row=4 ,1 is repeated two times, I again keep the most left one and replace any the right item which has the same value.
In row =5, 4 is repeated two times again. I keep the most left item, and then replace any item after that with the same value with N.
So for N= 9, the result would be:
[[2 5 1 4 3]
[1 6 4 2 3]
[0 9 9 6 9]
[2 1 9 3 9]
[4 9 1 2 3]]
I have the correct code in numpy below:
numpy code: (a2[:,1:])[a2[:,1:]==a2[:,:-1]] = N
but I need to do it in tensorflow , I tried the below code though it still raises the same error:
tf.where(tf.equal(a2[:,1:], a2[:, :-1]),N,a2[:,1:])
The error:
a2[:,1:][a2[:,1:]==a2[:,:-1]] = N
TypeError: 'Tensor' object does not support item assignment
I also looked at the links with the same error here, but they propose a solution exactly regarding their coding which did not match my code.
Thank you in advance
As the error message says, " 'Tensor' object does not support item assignment". But there are at least one workaround. One method is to element-wise multiply each element you want to change by zero (in the original matrix) and then create a new matrix (same shape) with all element zeros without the one you want to change. And then you can just add them together to get the desired matrix.
If i understand you're numpy solution correctly for this specific case, you always want to ignore the first column? If that is so, I think this tensorflow solution should work for you (tested and verified for tensorflow version 1.13.1).
import tensorflow as tf
tf.enable_eager_execution()
tf_a2 = tf.Variable(([[2, 5, 1, 4, 3],
[1, 6, 4, 2, 3],
[0, 0, 0, 6, 6],
[2, 1, 1, 3, 3],
[4, 4, 1, 2, 3]]))
N=9
first_col_change = tf.zeros([tf_a2.shape[0],1], dtype=tf.int32)
last_cols_change = tf.cast(tf.equal(tf_a2[:,1:], tf_a2[:, :-1]),tf.int32)
change_bool = tf.concat([first_col_change, last_cols_change],axis=-1)
not_change_bool = 1-change_bool
tf_a2_changed = tf_a2*not_change_bool + change_bool*N
print(tf_a2_changed)
which gives the output:
tf.Tensor(
[[2 5 1 4 3]
[1 6 4 2 3]
[0 9 9 6 9]
[2 1 9 3 9]
[4 9 1 2 3]], shape=(5, 5), dtype=int32)

Vectorized Update numpy array using another numpy array elements as index

Let A,C and B be numpy arrays with the same number of rows.
I want to update 0th element of A[0], 2nd element of A[1] etc. That is, update B[i]th element of A[i] to C[i]
import numpy as np
A = np.array([[1,2,3],[3,4,5],[5,6,7],[0,8,9],[3,7,5]])
B = np.array([0,2,1,2,0])
C = np.array([8,9,6,5,4])
for i in range(5):
A[i, B[i]] = C[i]
print ("FOR", A)
A = np.array([[1,2,3],[3,4,5],[5,6,7],[0,8,9],[3,7,5]])
A[:,B[:]] = C[:]
print ("Vectorized, A", A)
Output:
FOR [[8 2 3]
[3 4 9]
[5 6 7]
[0 8 5]
[4 7 5]]
Vectorized, A [[4 6 5]
[4 6 5]
[4 6 5]
[4 6 5]
[4 6 5]]
The for loop and vectorization gave different results.
I am unsure how to vectorize this for loop using Numpy.
The reason that your approach doesn't work is that you're passing the whole B as the column index and replace them with C instead you need to specify both row index and column index. Since you just want to change the first 4 rows you can simply use np.arange(4) to select the rows B[:4] the columns and C[:4] the replacement items.
In [26]: A[np.arange(4),B[:4]] = C[:4]
In [27]: A
Out[27]:
array([[8, 2, 3],
[3, 4, 9],
[5, 6, 7],
[0, 8, 5],
[3, 7, 5]])
Note that if you wanna update the whole array, as mentioned in comments by #Warren you can use following approach:
A[np.arange(A.shape[0]), B] = C

Slice 2-D array row by row with corresponding rows from identically shaped array [duplicate]

This question already has answers here:
Indexing one array by another in numpy
(4 answers)
Closed 6 years ago.
consider the array a
np.random.seed([3,1415])
a = np.random.choice(np.arange(8), (2, 4), False)
print(a)
[[7 1 4 5]
[6 2 3 0]]
I'll create another array b that holds the results of np.argsort along each row.
b = a.argsort(1)
print(b)
[[1 2 3 0]
[3 1 2 0]]
I want to produce the sorted version of a by doing an appropriate slice of a with b. It should look like this
idx0 = np.arange(a.shape[0]).repeat(a.shape[1])
print(a[idx0, b.ravel()].reshape(a.shape))
[[1 4 5 7]
[0 2 3 6]]
question
what is the appropriate way to slice an 2 x 4 array with another 2 x 4 array in the fashion described above?
Advanced-indexing for the help -
a[np.arange(b.shape[0])[:,None],b]
Sample run -
In [10]: a
Out[10]:
array([[7, 1, 4, 5],
[6, 2, 3, 0]])
In [11]: b
Out[11]:
array([[1, 2, 3, 0],
[3, 1, 2, 0]])
In [12]: a[np.arange(b.shape[0])[:,None],b]
Out[12]:
array([[1, 4, 5, 7],
[0, 2, 3, 6]])

Categories

Resources