Have the following:
In [14]: A = array([[1, 1], [3, 2], [-4, 1]])
In [15]: A
Out[15]:
array([[ 1, 1],
[ 3, 2],
[-4, 1]])
In [16]: x = array([1, 1])
In [17]: x
Out[17]: array([1, 1])
In [18]: dot(A, x)
Out[18]: array([ 2, 5, -3])
I was expecting a column, because dot() function is described as an ordinary matrix multiplication.
Why does it return a row instead? This behaviour seems very discouraging.
x a 1D vector, and as such has no notion of whether it's a row vector or a column vector. Same goes for the result of dot(A, x).
Turn x into a 2D array, and all will be well:
In [7]: x = array([[1], [1]])
In [8]: x
Out[8]:
array([[1],
[1]])
In [9]: dot(A, x)
Out[9]:
array([[ 2],
[ 5],
[-3]])
Finally, if you prefer to use more natural matrix notation, convert A to numpy.matrix:
In [10]: A = matrix(A)
In [11]: A * x
Out[11]:
matrix([[ 2],
[ 5],
[-3]])
Related
I use boolean indexing to select elements from a numpy array as
x = y[t<tmax]
where t a numpy array with as many elements as y. My question is how can I do the same with 2D numpy arrays? I tried
x = y[t<tmax][t<tmax]
This does not seem to work however since it seems to select first the rows and then complains that the second selection has the wrong dimension.
IndexError: boolean index did not match indexed array along dimension 0; dimension is 50 but corresponding boolean dimension is 200
#
Here is an example
x1D = np.array([1,2,3], np.int32)
x2D = np.array([[1,2,3],[1,2,3],[1,2,3]], np.int32)
print(x1D[x1D<3]) --> [1 2]
print(x2D[x1D<3][x1D<3]) --> error
The second print statement produces an error similar to the error shown above. I use
print(x2D[x1D<3])
I get
[[1 2 3]
[1 2 3]]
but I want
[[1 2]
[1 2]]
In [28]: x1D = np.array([1,2,3], np.int32)
...: x2D = np.array([[1,2,3],[1,2,3],[1,2,3]], np.int32)
The 1d mask:
In [29]: x1D<3
Out[29]: array([ True, True, False])
applied to the 1d array (same size):
In [30]: x1D[_]
Out[30]: array([1, 2], dtype=int32)
applied to the 2d it selects 2 rows:
In [31]: x2D[_29]
Out[31]:
array([[1, 2, 3],
[1, 2, 3]], dtype=int32)
It can be used again to select columns - but note the : place holder for the row index:
In [32]: _[:, _29]
Out[32]:
array([[1, 2],
[1, 2]], dtype=int32)
If we generate an indexing array from that mask, we can do the indexing with one step:
In [37]: idx = np.nonzero(x1D<3)
In [38]: idx
Out[38]: (array([0, 1]),)
In [39]: x2D[idx[0][:,None], idx[0]]
Out[39]:
array([[1, 2],
[1, 2]], dtype=int32)
An alternate way of writing this '2d' indexing:
In [41]: x2D[ [[0],[1]], [[0,1]] ]
Out[41]:
array([[1, 2],
[1, 2]], dtype=int32)
ix_ is a convenient tool for tweaking the indexing dimensions:
In [42]: x2D[np.ix_(idx[0], idx[0])]
Out[42]:
array([[1, 2],
[1, 2]], dtype=int32)
Or passing the boolean mask to ix_:
In [44]: np.ix_(_29, _29)
Out[44]:
(array([[0],
[1]]), array([[0, 1]]))
In [45]: x2D[np.ix_(_29, _29)]
Out[45]:
array([[1, 2],
[1, 2]], dtype=int32)
Writing In[32] so it's close to to your try:
In [46]: x2D[x1D<3][:, x1D<3]
Out[46]:
array([[1, 2],
[1, 2]], dtype=int32)
I have the following arrays:
a = np.arange(12).reshape((2, 2, 3))
and
b = np.zeros((2, 2))
Now I want to use b to access a, s.t. at each for index i,j we take the z-th element of a, if b[i, j] = z.
Meaning for the above example the answer should be [[0, 3], [6, 9]].
I feel this is very related to np.choose, but yet somehow cannot quite manage it.
Can you help me?
Two approaches could be suggested.
With explicit range arrays for advanced-indexing -
m,n = b.shape
out = a[np.arange(m)[:,None],np.arange(n),b.astype(int)]
With np.take_along_axis -
np.take_along_axis(a,b.astype(int)[...,None],axis=2)[...,0]
Sample run -
In [44]: a
Out[44]:
array([[[ 0, 1, 2],
[ 3, 4, 5]],
[[ 6, 7, 8],
[ 9, 10, 11]]])
In [45]: b
Out[45]:
array([[0., 0.],
[0., 0.]])
In [46]: m,n = b.shape
In [47]: a[np.arange(m)[:,None],np.arange(n),b.astype(int)]
Out[47]:
array([[0, 3],
[6, 9]])
In [48]: np.take_along_axis(a,b.astype(int)[...,None],axis=2)[...,0]
Out[48]:
array([[0, 3],
[6, 9]])
Suppose that I have define one 2x2 matrix using numpy:
array([[1, 2],
[2, 3]])
Now the other 2x1 matrix:
array([[3],
[4]])
How can I concatenate these 2 matrix by column, so that it will become:
array([[1, 2, 3],
[2, 3, 4]])
And how can I also delete the specify column, so that it will became
array([[1],
[2]])
There is a numpy.concatenate method
import numpy as np
np.concatenate( [ np.array( [ [1,2], [2,3] ] ), np.array( [ [3],[4] ] ) ] , axis = 1)
or simply use hstack or vstack
np.hstack( [ np.array( [ [1,2], [2,3] ] ), np.array( [ [3],[4] ] ) ] )
These can be also used to remove the column (concatenate two subarrays) - this can be used to remove many columns.
To remove i'th column you can take subarrays to this column, and from the next one, and concatenate them. For example, to remove second column (index 1):
a - np.array( [ [1,2,3], [2,3,4] ] )
a1= a[:,:1]
a2= a[:,2:]
np.hstack([a1,a2])
so in general
def remove_column( a, i ):
return np.hstack( [a[:,:i], a[:,(i+1):] ] )
and then
>>> remove_column(a, 1)
array([[1, 3],
[2, 4]])
>>> remove_column(a, 0)
array([[2, 3],
[3, 4]])
Actually, as pointed out in the comment - numpy implements its own delete method
np.delete(a, 1, 1)
deleted second column
and deleting multiple ones can be performed using
np.delete(a, [column1, columne2, ..., columnK], 1)
The third argument is the axis specifier, 0 would imply rows, 1 columns, None flatterns the whole array
You can use numpy.hstack:
>>> import numpy as np
>>> a = np.array([[1,2], [2,3]])
>>> b = np.array([[3], [4]])
>>> np.hstack((a,b))
array([[1, 2, 3],
[2, 3, 4]])
Removing is even easier, just slice:
>>> c = a[:,:1]
array([[1],
[2]])
In [3]: x = np.array([[1, 2], [2, 3]]
In [4]: y = np.array([[3], [4]])
In [9]: z = np.hstack([x, y])
In [10]: z
Out[10]:
array([[1, 2, 3],
[2, 3, 4]])
In [11]: z[:,:1]
array([[1],
[2]])
I have a 2D array:
>>> in_arr = np.array([[1,2],[4,3]])
array([[1, 2],
[4, 3]])
and I find the sorted indices by columns to yield another 2D array:
>>> col_sort = np.argsort(in_arr, axis=1)
array([[0, 1],
[1, 0]])
I would like to know the efficient numpy slice to index the first by the second:
>>> redordered_in_arr = np.*SOME_SLICE_METHOD*(in_arr, col_sort, axis=1)
array([[1, 2],
[3, 4]])
The intention is to then perform a (more complicated) function on the array by column, e.g.:
>>> arr_with_function = reordered_in_arr ** np.array([1,2])
array([[1, 4],
[3, 16]])
and return the elements to their original position in the array
>>> return_order = np.argsort(col_sort, axis=1)
>>> redordered_in_arr = np.*SOME_SLICE_METHOD*(arr_with_function, return_order, axis=1)
array([[1, 4],
[16, 3]])
Ok so thinking about it as I type I might just use apply_over_axis, but I would still like know how to the above efficiently in case it is of value later..
If you want to do all those operations in-place then you don't need argsort(). Numpy supports in-place operations in such situations:
In [12]: in_arr = np.array([[1,2],[4,3]])
In [13]: in_arr.sort(axis=1)
In [14]: in_arr **= [1, 2]
In [15]: in_arr
Out[15]:
array([[ 1, 4],
[ 3, 16]])
But if you need the indices of the sorted items you can get the expected result with a simple indexing.
In [18]: in_arr[np.arange(2)[:,None], col_sort]
Out[18]:
array([[1, 2],
[3, 4]])
I have searched long and hard for an answer to this question, but haven't found anything that quite fits the bill. I have a multidimensional numpy array containing data (in my case 3 dimensional) and another array (2 dimensional) that contains information on which value I want along the last dimension of the original array. For instance, here is a simple example illustrating the problem. I have an array a of data, and another array b containing indices along dimension 2 of a. I want a new two dimensional array c where c[i, j] = a[i, j, b[i, j]].The only way that I can think to do it is with a loop, as outlined below. However, this seems clunky and slow.
In [3]: a = np.arange(8).reshape((2, 2, 2))
In [4]: a
Out[4]:
array([[[0, 1],
[2, 3]],
[[4, 5],
[6, 7]]])
In [6]: b = np.array([[0, 1], [1, 1]])
In [8]: c = np.zeros_like(b)
In [9]: for i in xrange(2):
...: for j in xrange(2):
...: c[i, j] = a[i, j, b[i, j]]
In [10]: c
Out[10]:
array([[0, 3],
[5, 7]])
Is there a more pythonic way of doing this, perhaps some numpy indexing feature of which I am unaware?
When you fancy-index a multidimensional array with multidimensional arrays, the indices for each dimension are broadcasted together. With that in mind, you can do:
>>> rows = np.arange(a.shape[0])
>>> cols = np.arange(a.shape[1])
>>> a[rows[:, None], cols, b]
array([[0, 3],
[5, 7]])
In [40]: a = np.arange(8).reshape((2, 2, 2))
In [41]: b = np.array([[0, 1], [1, 1]])
In [42]: i = np.array([[0,0],[1,1]])
In [43]: a[i,i.T,b]
Out[43]:
array([[0, 3],
[5, 7]])
or using ix_ to generate the indexes:
In [47]: j = np.ix_([0,1],[0,1])
In [48]: a[j[0],j[1],b]
Out[48]:
array([[0, 3],
[5, 7]])
In [49]: j
Out[49]:
(array([[0],
[1]]), array([[0, 1]]))
or with ogrid
In [101]: i = np.ogrid[0:2,0:2]
In [102]: i.append(b)
In [103]: a[i]
Out[103]:
array([[0, 3],
[5, 7]])