I have the following list of indices [2 4 3 4] which correspond to my target indices. I'm creating a matrix of zeroes with the following line of code targets = np.zeros((features.shape[0], 5)). Im wondering if its possible to slice in such a way that I could update the specific indices all at once and set those values to 1 without a for loop, ideally the matrix would look like
([0,0,1,0,0], [0,0,0,0,1], [0,0,0,1,0], [0,0,0,0,1])
I believe you can do something like this:
targets = np.zeros((4, 5))
ind = [2, 4, 3, 4]
targets[np.arange(0, 4), ind] = 1
Here is the result:
array([[ 0., 0., 1., 0., 0.],
[ 0., 0., 0., 0., 1.],
[ 0., 0., 0., 1., 0.],
[ 0., 0., 0., 0., 1.]])
Related
How could the following MATLAB code be written using NumPy?
A = zeros(5, 100);
x = ones(5,1);
A(:,1) = x;
Assigning to rows seems to work easily, but I couldn't find an example of assigning an array to a column of another array.
Use a[:,1] = x[:,0]. You need x[:,0] to select the column of x as a single numpy array. If you have the choice of how to format x, it's better to not make it a 2-dimensional array in the first place, but just a regular (row) array:
>>> a
array([[ 0., 0., 0.],
[ 0., 0., 0.],
[ 0., 0., 0.],
[ 0., 0., 0.],
[ 0., 0., 0.]])
>>> x = numpy.ones(5)
>>> x
array([ 1., 1., 1., 1., 1.])
>>> a[:,1] = x
>>> a
array([[ 0., 1., 0.],
[ 0., 1., 0.],
[ 0., 1., 0.],
[ 0., 1., 0.],
[ 0., 1., 0.]])
>>> A = np.zeros((5,100))
>>> x = np.ones((5,1))
>>> A[:,:1] = x
I have three two dimensional Numpy arrays x, w, d and want to create a fourth one called a. w and d define only the shape of a with d.shape + w.shape. I want to have x in the entries of a with a zeros elsewhere.
Specifically, I want a loop-free version of this code:
a = np.zeros(d.shape + w.shape)
for j in range(d.shape[1]):
a[:,j,:,j] = x
For example, given:
x = np.array([
[2, 3],
[1, 1],
[8,10],
[0, 1]
])
w = np.array([
[ 0, 1, 1],
[-1,-2, 1]
])
d = np.matmul(x,w)
I want a to be
array([[[[ 2., 0., 0.],
[ 3., 0., 0.]],
[[ 0., 2., 0.],
[ 0., 3., 0.]],
[[ 0., 0., 2.],
[ 0., 0., 3.]]],
[[[ 1., 0., 0.],
[ 1., 0., 0.]],
[[ 0., 1., 0.],
[ 0., 1., 0.]],
[[ 0., 0., 1.],
[ 0., 0., 1.]]],
[[[ 8., 0., 0.],
[10., 0., 0.]],
[[ 0., 8., 0.],
[ 0., 10., 0.]],
[[ 0., 0., 8.],
[ 0., 0., 10.]]],
[[[ 0., 0., 0.],
[ 1., 0., 0.]],
[[ 0., 0., 0.],
[ 0., 1., 0.]],
[[ 0., 0., 0.],
[ 0., 0., 1.]]]])
This answer inspired the following solution:
# shape a: (4, 3, 2, 3)
# shape x: (4, 2)
a = np.zeros(d.shape + w.shape)
a[:, np.arange(a.shape[1]), :, np.arange(a.shape[3])] = x
It uses Numpy's broadcasting (see here or here) im combination with Advanced Indexing to enlarge x to fit the slicing.
I happen to have an even simpler solution: a = np.tensordot(x, np.identity(3), axes = 0).swapaxes(1,2)
The size of the identity matrix will be decided by the number of times you wish to repeat the elements of x.
I want to create a matrix with Numpy, but I need to add every element by its row and column indices.
for example:
my_matrix = np.matrix(np.zeros((5, 5)))
my_matrix.insert(row_index=2, column_index=1, value=10)
output:
matrix([[0., 0., 0., 0., 0.],
[10., 0., 0., 0., 0.],
[0., 0., 0., 0., 0.],
[0., 0., 0., 0., 0.],
[0., 0., 0., 0., 0.]])
How can I do that?
Do you want to add or insert values?
The add function that you mentioned is used as an element-wise addition.
Example:
np.add([1, 2], [2, 3])
Out[41]: array([3, 5])
If you really want to create a matrix a matrix by inserting values with column and row indices, create the matrix first and insert your values afterwards.
number_rows = 10
number_cols = 20
arr = np.empty((number_rows, number_cols))
arr[2, 1] = 10
The use of np.matrix is discouraged, if not actually deprecated. It is rarely needed, except for some backward compatibility cases.
In [1]: arr = np.zeros((5,5))
In [2]: arr
Out[2]:
array([[0., 0., 0., 0., 0.],
[0., 0., 0., 0., 0.],
[0., 0., 0., 0., 0.],
[0., 0., 0., 0., 0.],
[0., 0., 0., 0., 0.]])
In [3]: mat = np.matrix(arr)
In [4]: mat
Out[4]:
matrix([[0., 0., 0., 0., 0.],
[0., 0., 0., 0., 0.],
[0., 0., 0., 0., 0.],
[0., 0., 0., 0., 0.],
[0., 0., 0., 0., 0.]])
Indexing one row of arr produces a 1d array
In [5]: arr[2]
Out[5]: array([0., 0., 0., 0., 0.])
Indexing one row of mat produces a 2d matrix, with shape (1,5)
In [6]: mat[2]
Out[6]: matrix([[0., 0., 0., 0., 0.]])
We can access an element in the 1d array:
In [7]: arr[2][1]
Out[7]: 0.0
but this indexing of the mat tries to access a row, and gives an error:
In [8]: mat[2][1]
---------------------------------------------------------------------------
IndexError Traceback (most recent call last)
<ipython-input-8-212ad5378f8e> in <module>
----> 1 mat[2][1]
...
IndexError: index 1 is out of bounds for axis 0 with size 1
In both cases it is better to access an element with the tuple syntax, rather than the chained one:
In [9]: arr[2,1]
Out[9]: 0.0
In [10]: mat[2,1]
Out[10]: 0.0
This indexing also works for setting values. But try to avoid iterating to set individual values. Try to find ways of creating the whole array with the desired values directly, with whole array methods, not iteration.
A is an numpy array with shape (6, 8)
I want:
x_id = np.array([0, 3])
y_id = np.array([1, 3, 4, 7])
A[ [x_id, y_id] += 1 # this doesn't actually work.
Tricks like ::2 won't work because the indices do not increase regularly.
I don't want to use extra memory to repeat [0, 3] and make a new array [0, 3, 0, 3] because that is slow.
The indices for the two dimensions do not have equal length.
which is equivalent to:
A[0, 1] += 1
A[3, 3] += 1
A[0, 4] += 1
A[3, 7] += 1
Can numpy do something like this?
Update:
Not sure if broadcast_to or stride_tricks is faster than nested python loops. (Repeat NumPy array without replicating data?)
You can convert y_id to a 2d array with the 2nd dimension the same as x_id, and then the two indices will be automatically broadcasted due to the dimension difference:
x_id = np.array([0, 3])
y_id = np.array([1, 3, 4, 7])
A = np.zeros((6,8))
A[x_id, y_id.reshape(-1, x_id.size)] += 1
A
array([[ 0., 1., 0., 0., 1., 0., 0., 0.],
[ 0., 0., 0., 0., 0., 0., 0., 0.],
[ 0., 0., 0., 0., 0., 0., 0., 0.],
[ 0., 0., 0., 1., 0., 0., 0., 1.],
[ 0., 0., 0., 0., 0., 0., 0., 0.],
[ 0., 0., 0., 0., 0., 0., 0., 0.]])
I have a sparse 2D matrix, typically something like this:
test
array([[ 1., 0., 0., 0.],
[ 0., 0., 0., 0.],
[ 0., 2., 1., 0.],
[ 0., 0., 0., 1.]])
I'm interested in all nonzero elements in "test"
index = numpy.nonzero(test) returns a tuple of arrays giving me the indices for the nonzero elements:
index
(array([0, 2, 2, 3]), array([0, 1, 2, 3]))
For each row I would like to print out all the nonzero elements, but skipping all rows containing only zero elements.
I would appreciate hints for this.
Thanks for the hints. This solved the problem:
>>> test
array([[ 1., 0., 0., 0.],
[ 0., 0., 0., 0.],
[ 0., 2., 1., 0.],
[ 0., 0., 0., 1.]])
>>> transp=np.transpose(np.nonzero(test))
>>> transp
array([[0, 0],
[2, 1],
[2, 2],
[3, 3]])
>>> for index in range(len(transp)):
row,col = transp[index]
print 'Row index ',row,'Col index ',col,' value : ', test[row,col]
giving me:
Row index 0 Col index 0 value : 1.0
Row index 2 Col index 1 value : 2.0
Row index 2 Col index 2 value : 1.0
Row index 3 Col index 3 value : 1.0
Given
rows, cols = np.nonzero(test)
you could also use so-called advanced integer indexing:
test[rows, cols]
For example,
test = np.array([[ 1., 0., 0., 0.],
[ 0., 0., 0., 0.],
[ 0., 2., 1., 0.],
[ 0., 0., 0., 1.]])
rows, cols = np.nonzero(test)
print(test[rows, cols])
yields
array([ 1., 2., 1., 1.])
Use array indexing:
test[test != 0]
There is no array operation to do this per-row (instead of for the entire matrix), as that would return a variable number of elements per row. You can use something like
[row[row != 0] for row in test]
to achieve that.