So, I'm new to python and learning about the NumPy module.
Here is my array
c = np.array([[[ 0, 1, 2],
[ 10, 12, 13]],
[[100, 101, 102],
[110, 112, 113]]])
in the above array if I try to access it through
c[:1,0:]
it produces expected output that
# expected because print from initial to row 1,0 excluding row 1,0
array([[[ 0, 1, 2],
[10, 12, 13]]])
but now when I try to access it through
c[:1,1:]
it produces output that
array([[[10, 12, 13]]])
why???
This is a 3D array. You can check it with
print(c.shape)
that yields
(2, 2, 3)
Is 3D array really what you wish to do ?
If so, if you slice it with two indices instead of three, that means that the third is implicitly :. So c[1, 1] is equivalent to c[1, 1, :] which is equivalent to c[1, 1, 0:3].
And your query c[:1,1:] is equivalent to c[0, 1, 0:3]: that is the correct result.
Now as per your comment I guess you wish to reshape, filter and reshape:
c.reshape(4, -1)[:3,:].reshape(1, 3, -1)
yields
array([[[ 0, 1, 2],
[ 10, 12, 13],
[100, 101, 102]]])
Related
I want to compute the element-wise tensor product of 2 tensors of the shape (1144,3) meaning I want to compute the tensordot along the second axis if I understood it correctly.
I'd expect my result to be of the shape (1144,3,3).
I am currently trying to achieve this using numpys tensordot() function, but I can't figure out the correct axes to use to get a shape of (1144,3,3).
You can use numpy.einsum for this.
In [30]: a
Out[30]:
array([[0, 1, 2],
[3, 4, 5]])
In [31]: np.einsum('ij,ik->ijk', a, a)
Out[31]:
array([[[ 0, 0, 0],
[ 0, 1, 2],
[ 0, 2, 4]],
[[ 9, 12, 15],
[12, 16, 20],
[15, 20, 25]]])
As numpy.tensordot support only 2 element axes this means there is no way to imitate the
->...-like behavior. So I don't see how this can be done with numpy.tensordot.
I want to add a list of elements at the end of the arrays of a list. I tried to use np.insertfunction like this :
dataForModel=np.insert(dataForModel, -1, output_recoded, axis=1)
where dataForModel is a list of arrays and sampling_timesis a 1-D list whose length is the same as len(dataForModel). So what I want is to put one (corresponding) element of output_recodedat the end of each array contained in dataForModel
The problem is, it puts output_recoded before the last column of the basic dataForModelbut I want it to be after.
For example if my data were dataForModel=[array([2,15,-3,4]), array([12,1,3,42]),array([6,8,21,-5])] and output_recoded is [101,47,82], I would like to have [array([2,15,-3,4,101]), array([12,1,3,42,47]),array([6,8,21,-5,82])]
Thanks for help
Try this:
dataForModel=np.insert(dataForModel, dataForModel.size, sampling_times, axis=1)
Example:
>>> a = np.array([2, 56, 4, 8, 564])
>>> np.insert(a, -1, [1,2,3])
array([ 2, 56, 4, 8, 1, 2, 3, 564])
>>> np.insert(a, a.size, [1,2,3])
array([ 2, 56, 4, 8, 564, 1, 2, 3])
Update:
>>> dataForModel=[np.array([2,15,-3,4]), np.array([12,1,3,42]),np.array([6,8,21,-5])]
>>> dataForModel=np.array(dataForModel)
>>> dataForModel
array([[ 2, 15, -3, 4],
[12, 1, 3, 42],
[ 6, 8, 21, -5]])
>>> output_recoded= [101,47,82]
>>> dataForModel=np.insert(dataForModel, dataForModel.shape[1], output_recoded, axis=1)
>>> dataForModel
array([[ 2, 15, -3, 4, 101],
[ 12, 1, 3, 42, 47],
[ 6, 8, 21, -5, 82]])
If you are trying to add an ending column, keep in mind the data added needs to match the dimensions of (dataForModel.shape[1],1) dimension
My first bet would be a for loop, though there are probably more efficient ways to do this:
for i in range(len(dataForModel)):
dataForModel[i] = [*dataForModel[i], sampling_times[i]]
The * will unpack the current array into a new list, though you could append as well
for a value x I want to create a numpy array of the form [1,x,x^2,x^3,...,x^n]. I found the function numpy.fromfunction, but i can't get it working. I tried the following:
np.fromfunction(lambda i: np.power(x,i), 10, dtype=int)
Can somebody explain why this doesn't work and how I can do this?
I know I can do this with a for loop, but I would prefer to use a numpy function.
If you have your variable x then you can just do
>>> x = 3
>>> np.power(x, np.arange(10))
array([ 1, 3, 9, 27, 81, 243, 729, 2187, 6561, 19683], dtype=int32)
If you want x to be a matrix, just ensure that the dimensions are compatible, e.g.
>>> x = np.array([[1, 1, 1],
[2, 2, 2],
[3, 3, 3],
[4, 4, 4]])
>>> np.power(x, np.arange(3))
array([[ 1, 1, 1],
[ 1, 2, 4],
[ 1, 3, 9],
[ 1, 4, 16]], dtype=int32)
CoryKramer answer is likely the best way of achieving your desired result, but if you wanted to adapt your current approach to the problem, the code below would work:
np.fromfunction(lambda _, i: np.power(x,i), (1, 10), dtype=int)
For x = 3, this produces:
[ 1, 3, 9, 27, 81, 243, 729, 2187, 6561, 19683]
This is because you were providing the value 10 for the array shape, instead of an iterable. The lambda function must then accept two values, so _ is used to collect the first value (which is always 0 for an array with the shape (1, 10)).
I have a 3D matrix X which contains vectors as rows into the 3rd dimension. I would like to extract each such vector X(:, x, y) and save it as a 2D matrix such that X(:, 0, 0) is the first row of the 2D matrix, X(:, 0, 1) the second, and so on. The following crude graphic might help illustrate this:
I know that I can create my new 2D matrix and then iterate over the original X to add the vectors, but does somebody have some input on how to do this quick and efficiently?
Example: Given
>>> a = np.arange(9*3).reshape(3,3,3)
>>> a
array([[[ 0, 1, 2],
[ 3, 4, 5],
[ 6, 7, 8]],
[[ 9, 10, 11],
[12, 13, 14],
[15, 16, 17]],
[[18, 19, 20],
[21, 22, 23],
[24, 25, 26]]])
I would like to get the following as rows, though the order of the rows does not matter:
array([[ 0, 9, 18],
[ 1, 10, 19]],
...)
Use np.transpose and then reshape like so -
X.transpose(1,2,0).reshape(-1,X.shape[0])
Explanation -
1) You want to get rows formed off X[:, 0, 0], X[:, 0, 1], etc., i.e., we have to "push" the axis=0 elements to the last axis of such a 2D array output. Next up, we have to decided the order of rows, which would be formed out of axes=1,2 from it. Now, going back to the desired 2D array output, between the first and second rows, i.e. between X[:, 0, 0] and X[:, 0, 1], axis=1 stays the same. So, in the 2D array output, the second axis (axis=1) would have precedence over the third axis (axis=2). So, in X we push axis=1 to axis=0 and axis=2 to axis=1. Since, as stated earlier axis=0 in X had to be moved to the last axis, so that would be axis=2. All of this could be done with X.transpose(1,2,0). Let's call it Y .
2) Finally, we have to reshape Y to a 2D array such that the number of elements in each row is same as X.shape[0], which is achieved through Y.reshape(-1,X.shape[0]). Thus, the final solution becomes -
X.transpose(1,2,0).reshape(-1,X.shape[0])
Sample run -
In [25]: X
Out[25]:
array([[[ 0.19508052, 0.02481975],
[ 0.88915956, 0.95974095]],
[[ 0.23271151, 0.14730822],
[ 0.56763563, 0.30607283]],
[[ 0.33259228, 0.42552102],
[ 0.28950926, 0.47782175]]])
In [26]: X[:, 0, 0]
Out[26]: array([ 0.19508052, 0.23271151, 0.33259228])
In [27]: X[:, 0, 1]
Out[27]: array([ 0.02481975, 0.14730822, 0.42552102])
In [28]: X[:, 1, 0]
Out[28]: array([ 0.88915956, 0.56763563, 0.28950926])
In [29]: X[:, 1, 1]
Out[29]: array([ 0.95974095, 0.30607283, 0.47782175])
In [30]: X.transpose(1,2,0).reshape(-1,X.shape[0])
Out[30]:
array([[ 0.19508052, 0.23271151, 0.33259228],
[ 0.02481975, 0.14730822, 0.42552102],
[ 0.88915956, 0.56763563, 0.28950926],
[ 0.95974095, 0.30607283, 0.47782175]])
I am trying to improve my understanding of numpy functions. I understand the behaviour of numpy.dot. I'd like to understand the behaviour of numpy.outer in terms of numpy.dot.
Based on this Wikipedia article https://en.wikipedia.org/wiki/Outer_product I'd expect for array_equal to return True in the following code. However it does not.
X = np.matrix([
[1,5],
[5,9],
[4,1]
])
r1 = np.outer(X,X)
r2 = np.dot(X, X.T)
np.array_equal(r1, r2)
How can I assign r2 so that np.array_equal returns True? Also, why does numpy's implementation of np.outer not match the definition of outer multiplication on Wikipedia?
Using numpy 1.9.2
In [303]: X=np.array([[1,5],[5,9],[4,1]])
In [304]: X
Out[304]:
array([[1, 5],
[5, 9],
[4, 1]])
In [305]: np.inner(X,X)
Out[305]:
array([[ 26, 50, 9],
[ 50, 106, 29],
[ 9, 29, 17]])
In [306]: np.dot(X,X.T)
Out[306]:
array([[ 26, 50, 9],
[ 50, 106, 29],
[ 9, 29, 17]])
The Wiki outer link mostly talks about vectors, 1d arrays. Your X is 2d.
In [310]: x=np.arange(3)
In [311]: np.outer(x,x)
Out[311]:
array([[0, 0, 0],
[0, 1, 2],
[0, 2, 4]])
In [312]: np.inner(x,x)
Out[312]: 5
In [313]: np.dot(x,x) # same as inner
Out[313]: 5
In [314]: x[:,None]*x[None,:] # same as outer
Out[314]:
array([[0, 0, 0],
[0, 1, 2],
[0, 2, 4]])
Notice that the Wiki outer does not involve summation. Inner does, in this example 5 is the sum of the 3 diagonal values of the outer.
dot also involves summation - all the products followed summation along a specific axis.
Some of the wiki outer equations use explicit indices. The einsum function can implement these calculations.
In [325]: np.einsum('ij,kj->ik',X,X)
Out[325]:
array([[ 26, 50, 9],
[ 50, 106, 29],
[ 9, 29, 17]])
In [326]: np.einsum('ij,jk->ik',X,X.T)
Out[326]:
array([[ 26, 50, 9],
[ 50, 106, 29],
[ 9, 29, 17]])
In [327]: np.einsum('i,j->ij',x,x)
Out[327]:
array([[0, 0, 0],
[0, 1, 2],
[0, 2, 4]])
In [328]: np.einsum('i,i->',x,x)
Out[328]: 5
As mentioned in the comment, np.outer uses ravel, e.g.
return a.ravel()[:, newaxis]*b.ravel()[newaxis,:]
This the same broadcasted multiplication that I demonstrated earlier for x.
numpy.outer only works for 1-d vectors, not matrices. But for the case of 1-d vectors, there is a relation.
If
import numpy as np
A = np.array([1.0,2.0,3.0])
then this
np.matrix(A).T.dot(np.matrix(A))
should be the same as this
np.outer(A,A)
Another (clunky) version similar to a[:,None] * a[None,:]
a.reshape(a.size, 1) * a.reshape(1, a.size)