Namely, rearranging rows, adding multiples of rows, and multiplying by scalars.
I don't see these methods defined in http://docs.scipy.org/doc/numpy/reference/generated/numpy.matrix.html or elsewhere.
And if they aren't defined, then why not?
Yes, you can manipulate array rows, adding and multiplying them. For example:
In [1]: import numpy as np
In [2]: m = np.ones((3, 4))
In [3]: m
Out[3]:
array([[ 1., 1., 1., 1.],
[ 1., 1., 1., 1.],
[ 1., 1., 1., 1.]])
In [4]: m[1, :] = 2*m[1, :] # Multiply
In [5]: m
Out[5]:
array([[ 1., 1., 1., 1.],
[ 2., 2., 2., 2.],
[ 1., 1., 1., 1.]])
In [6]: m[0, :] = m[0, :] + 2*m[1, :] # Multiply and add
In [7]: m
Out[7]:
array([[ 5., 5., 5., 5.],
[ 2., 2., 2., 2.],
[ 1., 1., 1., 1.]])
In [8]: m[ (0, 2), :] = m[ (2, 0), :] # Swap rows
In [9]: m
Out[9]:
array([[ 1., 1., 1., 1.],
[ 2., 2., 2., 2.],
[ 5., 5., 5., 5.]])
Related
I have a 3-D numpy array representing a model domain of 39 layers, 279 rows, 153 columns. The values in the array are either 0 or 1 and signify if the cell in the domain is inactive or active, respectively. I am trying to create a 2-D array of shape 279 rows and 153 columns where the array values equal the layer number for the uppermost active layer in the grid. Essentially, at each row, col location I want to loop through the layers to find the first one that is a 1 and not a 0 and then put that layer number in the 2-D array at that row, col location. For example:
If a four layer (layers 0-3) array looks like this:
array([[[ 0., 1., 0., 0.],
[ 1., 0., 0., 0.],
[ 1., 0., 0., 0.]],
[[ 0., 1., 1., 0.],
[ 1., 1., 0., 0.],
[ 1., 1., 0., 0.]],
[[ 0., 0., 1., 1.],
[ 0., 1., 1., 0.],
[ 0., 1., 1., 0.]],
[[ 0., 0., 1., 1.],
[ 0., 1., 1., 1.],
[ 0., 1., 1., 1.]]])
The 2-D array should look like this:
array([[[ 0., 0., 1., 2.],
[ 0., 1., 2., 3.],
[ 0., 1., 2., 3.]],
If the row-col location is not active (not equal to 1) in any layer , the value in the resulting array should be 0 (like at 1,1), the same as if it were active in layer 0.
I have tried modifying a couple of solutions where the z-axis values are summed, or averaged, but can't seem to figure out how to get exactly what I am looking for.
You could try numpy.argmax:
import numpy as np
a = np.array([[[ 0., 1., 0., 0.],
[ 1., 0., 0., 0.],
[ 1., 0., 0., 0.]],
[[ 0., 1., 1., 0.],
[ 1., 1., 0., 0.],
[ 1., 1., 0., 0.]],
[[ 0., 0., 1., 1.],
[ 0., 1., 1., 0.],
[ 0., 1., 1., 0.]],
[[ 0., 0., 1., 1.],
[ 0., 1., 1., 1.],
[ 0., 1., 1., 1.]]])
print(np.argmax(a,0))
array([[0, 0, 1, 2],
[0, 1, 2, 3],
[0, 1, 2, 3]])
This works because argmax returns the first max value when searching over the defined axis (in this case the 0th axis).
Let's say I have the following array A -
import numpy as np
batch_size, seq_len = 3, 5
A = np.zeros((batch_size, seq_len))
A[0,0:] = 1
A[1,0:] = 2
A[2,0:] = 3
A has the following value -
array([[1., 1., 1., 1., 1.],
[2., 2., 2., 2., 2.],
[3., 3., 3., 3., 3.]])
Now, if I reshape it in the following way -
A4 = A.reshape(seq_len, -1)
array([[1., 1., 1.],
[1., 1., 2.],
[2., 2., 2.],
[2., 3., 3.],
[3., 3., 3.]])
However, I expected it to be -
array([[1., 2., 3.],
[1., 2., 3.],
[1., 2., 3.],
[1., 2., 3.],
[1., 2., 3.]])
Kudos to this awesome blog post bringing my attention to this problem - https://discuss.pytorch.org/t/for-beginners-do-not-use-view-or-reshape-to-swap-dimensions-of-tensors/75524
From the np.reshape docs
You can think of reshaping as first raveling the array (using the given index order), then inserting the elements from the raveled array into the new array using the same kind of index ordering as was used for the raveling.
a4 is (5,3) with the elements in the same order [1,1,1,1,1,2,2,...]
I have a list of arrays say
k=[array([0, 2], dtype=int64),
array([1], dtype=int64),
array([3, 4], dtype=int64)]
There is also an array
e=array([[0., 4., 0., 0.],
[1., 2., 2., 0.],
[0., 0., 2., 4.],
[0., 0., 0., 0.],
[0., 0., 0., 3.]])
I want to get an array x as follows
array([[0,4,2,4],
[1,2,2,0],
[0,0,0,3]])
Here
x[0] = e[0]+e[2]
x[1] = e[1]
x[2] = e[3]+e[4]
I want this in a vectorized fashion(without loops).Is this possible?
If the input arrays are all the same size, a full numpy solution is possible:
k = np.array([[0, 2], [1, 1], [3, 4]], dtype=int)
e = np.array([[0., 4., 0., 0.],
[1., 2., 2., 0.],
[0., 0., 2., 4.],
[0., 0., 0., 0.],
[0., 0., 0., 3.]])
e[k].sum(axis=1)
If not, using a loop is I think necessary:
import numpy as np
k = [np.array([0, 2], dtype=int),
np.array([1], dtype=int),
np.array([3, 4], dtype=int)]
e = np.array([[0., 4., 0., 0.],
[1., 2., 2., 0.],
[0., 0., 2., 4.],
[0., 0., 0., 0.],
[0., 0., 0., 3.]])
np.array([ e[ki, :].sum(axis=0) for ki in k ])
I have a numpy zero matrix A of the shape (2, 5).
A = [[ 0., 0., 0., 0., 0.],
[ 0., 0., 0., 0., 0.]]
I have another array seq of size 2. This is same as the first axis of A.
seq = [2, 3]
I want to create another matrix B which looks like this:
B = [[ 1., 1., 0., 0., 0.],
[ 1., 1., 1., 0., 0.]]
B is constructed by changing the first seq[i] elements in the ith row of A with 1.
This is a toy example. A and seq can be large so efficiency is required. I would be extra thankful if someone knows how to do this in tensorflow.
You can do this in TensorFlow (and with some analogous code in NumPy) as follows:
seq = [2, 3]
b = tf.expand_dims(tf.range(5), 0) # A 1 x 5 matrix.
seq_matrix = tf.expand_dims(seq, 1) # A 2 x 1 matrix.
b_bool = tf.greater(seq_matrix, b) # A 2 x 5 bool matrix.
B = tf.to_int32(b_bool) # A 2 x 5 int matrix.
Example output:
In [7]: b = tf.expand_dims(tf.range(5), 0)
[[0 1 2 3 4]]
In [21]: b_bool = tf.greater(seq_matrix, b)
In [22]: op = sess.run(b_bool)
In [23]: print(op)
[[ True True False False False]
[ True True True False False]]
In [24]: bint = tf.to_int32(b_bool)
In [25]: op = sess.run(bint)
In [26]: print(op)
[[1 1 0 0 0]
[1 1 1 0 0]]
This #mrry's solution, expressed a little differently
In [667]: [[2],[3]]>np.arange(5)
Out[667]:
array([[ True, True, False, False, False],
[ True, True, True, False, False]], dtype=bool)
In [668]: ([[2],[3]]>np.arange(5)).astype(int)
Out[668]:
array([[1, 1, 0, 0, 0],
[1, 1, 1, 0, 0]])
The idea is to compare [2,3] with [0,1,2,3,4] in an 'outer' broadcasting sense. The result is boolean which can be easily changed to 0/1 integers.
Another approach would be to use cumsum (or another ufunc.accumulate function):
In [669]: A=np.zeros((2,5))
In [670]: A[range(2),[2,3]]=1
In [671]: A
Out[671]:
array([[ 0., 0., 1., 0., 0.],
[ 0., 0., 0., 1., 0.]])
In [672]: A.cumsum(axis=1)
Out[672]:
array([[ 0., 0., 1., 1., 1.],
[ 0., 0., 0., 1., 1.]])
In [673]: 1-A.cumsum(axis=1)
Out[673]:
array([[ 1., 1., 0., 0., 0.],
[ 1., 1., 1., 0., 0.]])
Or a variation starting with 1's:
In [681]: A=np.ones((2,5))
In [682]: A[range(2),[2,3]]=0
In [683]: A
Out[683]:
array([[ 1., 1., 0., 1., 1.],
[ 1., 1., 1., 0., 1.]])
In [684]: np.minimum.accumulate(A,axis=1)
Out[684]:
array([[ 1., 1., 0., 0., 0.],
[ 1., 1., 1., 0., 0.]])
If I have two ndarrays:
a.shape # returns (200,300, 3)
b.shape # returns (200, 300)
numpy.vstack((a,b)) # Gives error
Would print out the error:
ValueError: arrays must have same number of dimensions
I tried doing vstack((a.reshape(-1,300), b) which kind of works, but the output is very weird.
You don't specify what final shape you actually want. If it's (200, 300, 4), you can use dstack instead:
>>> import numpy as np
>>> a = np.random.random((200,300,3))
>>> b = np.random.random((200,300))
>>> c = np.dstack((a,b))
>>> c.shape
(200, 300, 4)
Basically, when you're stacking, the lengths have to agree in all the other axes.
[Updated based on comment:]
If you want (800, 300) you could try something like this:
>>> a = np.ones((2, 3, 3)) * np.array([1,2,3])
>>> b = np.ones((2, 3)) * 4
>>> c = np.dstack((a,b))
>>> c
array([[[ 1., 2., 3., 4.],
[ 1., 2., 3., 4.],
[ 1., 2., 3., 4.]],
[[ 1., 2., 3., 4.],
[ 1., 2., 3., 4.],
[ 1., 2., 3., 4.]]])
>>> c.T.reshape(c.shape[0]*c.shape[-1], -1)
array([[ 1., 1., 1.],
[ 1., 1., 1.],
[ 2., 2., 2.],
[ 2., 2., 2.],
[ 3., 3., 3.],
[ 3., 3., 3.],
[ 4., 4., 4.],
[ 4., 4., 4.]])
>>> c.T.reshape(c.shape[0]*c.shape[-1], -1).shape
(8, 3)