I am trying to do inverse of numpy array,
from numpy import mat
from numpy import *
from numpy import matrix
from numpy import linalg
d =array ([ (0, 1, 2, 3, 4),
( 5, 6, 7, 8, 9),
(10, 11, 12, 13, 14)])
print d.T
print d.I
print d.diagonal
#above line gives <built-in method diagonal of numpy.ndarray object at 0x7fdf40a263f0>
print numpy.linalg.inv(d)
I am getting
AttributeError: 'numpy.ndarray' object has no attribute 'I'
any suggestion for this to get inverse and diagonal?
I would suggest changing all these imports:
from numpy import mat
from numpy import *
from numpy import matrix
from numpy import linalg
to just one:
import numpy as np
Then you can do
d = np.array(...)
# d = np.arange(15).reshape(3,5)
M = np.matrix(d)
M.I # a matrix has an I property, but an array does not
d.diagonal() # diagonal is a method, not a property
np.diagonal(d) # diagonal is also a function
np.linalg.inv(d) does not work - it gives an error objecting that the array is not square. So evidently M.I is returning a different kind of inverse. See my note below about pinv.
numpy (and Python in general) has functions, methods, and properties (attributes). Are the distinctions clear?
Many numpy functions end up calling the corresponding method for the main array object. Usually that doesn't matter much, except as a calling convenience.
np.matrix is one subclass that has many of its own methods. Note, for example
In [817]: M.diagonal()
Out[817]: matrix([[ 0, 6, 12]])
In [818]: d.diagonal()
Out[818]: array([ 0, 6, 12])
diagonal has returned the same numbers, but for M, it returns an object of the same class, and which by class definition is 2d.
d.T, M.I access properties. These don't require the () that a method does, but in many ways they are the same. np.matrix has defined I, but np.array has not.
If you are used to working with matrices in MATLAB, the np.matrix class may ease the transition. But if this is your first experience with arrays like this, I'd suggest sticking the np.array. The np.matrix class will just add confusion.
M.I is the same as M.getI().
It's code is (use help(M.getI) to read its docs)
def getI(self):
M, N = self.shape
if M == N:
from numpy.dual import inv as func
else:
from numpy.dual import pinv as func
return asmatrix(func(self))
So that means that M.I use pinv rather than inv. np.linalg.pinv(d) works.
You will get these methods if you transform d to a np.matrix, by doing:
d = np.matrix(d)
then:
d.I
d.diagonal()
will work.
A.diagonal is a method of numpy.ndarray, just as the print out suggests. Therefore, the solution of #Saullo Castro works for numpy arrays as well, without the need to convert to np.matrix.
import numpy as np
A = np.arange(25).reshape((5,5))
diag = A.diagonal()
# array([ 0, 6, 12, 18, 24])
Numpy Arrays have no method to calculate the inverse of a matrix, but you can easily do that with numpy.linalg.inv, just as you already tried according to your code example.
Related
now I have a numpy 2D array and want to make a convolution with a 2D kernel. I have tried using numpy.convolve and the out put was :
ValueError: object too deep for desired array
when trying signal.convolve it works well .
so is there any way to fix np.convolve??
and is the result of signal.convolve will be the same as np.convolve
?
here is my simple code:
import numpy as np
from scipy import signal
a=np.array([[1,2,3],[4,5,6]])
b=np.array([[1,1],[1,1]])
A=np.convolve(a,b,'same')
out:ValueError: object too deep for desired array
B=signal.convolve(a,b,'same')
Out[53]:
array([[ 1, 3, 5],
[ 5, 12, 16]])
I was reading the OpenCV python tutorials, and they said that the NumPy array function item() is the best way to access pixel values in an image, but I don't understand what it does.
import cv2
import numpy as np
img = cv2.imread('image.jpg')
print(img.item(10, 10, 2)) # I don't know what the item() function does/what it's parameters are
From the docs: numpy.ndarray.item() copies an element of an array to a standard Python scalar and returns it.
To put it in other words, calling img.item(i) gets you a copy of the value represented by the index i in your array, similar to img[i] but with the difference that it returns it as a Python scalar instead of an array. Following the docs, getting a Python scalar is useful to speed up access to the elements of the array and doing arithmetic on the values taking advantage of Python's optimized math.
An example:
>>> x = np.random.randint(9, size=(3, 3))
>>> x
array([[1, 8, 4],
[8, 7, 5],
[2, 1, 1]])
>>> x.item((1,0))
8
>>> x[1,0] # both calls seem to return the same value, but...
8
>>> type(x[1,0]) # Numpy's own int32
<class 'numpy.int32'>
>>> type(x.item((1,0))) # Python's standard int
<class 'int'>
item takes only one parameter which can be None, which only works with single item arrays, an int_type, which works like a flat index, and a tuple of int_type, which is interpreted as a multi dimension index of the array.
Going back to your concrete question, OpenCV recommends item and itemset when working with individual pixel values, as numpy is optimized for array calculations so accessing a single item is discouraged.
So instead of doing:
import cv2
import numpy as np
img = cv2.imread('image.jpg')
img[0, 0] = 255 # Setting a single pixel
px = img[0, 0] # Getting a single pixel
Do:
img.itemset((0, 0), 255)
px = img.item((0, 0))
I'm having trouble finding the proper way to do something I think should be trivial using numpy. I have an array (1000x1000) and I want to calculate the sum of a specific pattern across the array.
For example:
If I have this array and want to calculate the sum of a two-cell-right diagonal I would expect [7,12,11,8,12,6,11,7] (a total of 8 sums).
How can I do this?
This operation is called a 2-dimensional convolution:
>>> import numpy as np
>>> from scipy.signal import convolve2d
>>> kernel = np.eye(2, dtype=int)
>>> a = np.array([[5,3,7,1,2],[3,2,9,4,7],[8,9,4,2,3]])
>>> convolve2d(a, kernel, mode='valid')
array([[ 7, 12, 11, 8],
[12, 6, 11, 7]])
Should you want to generalize it to arbitrary dimensions, there is also scipy.ndimage.convolve available. It will also work for this 2d case, but does not offer the mode='valid' convenience.
l = [[5,3,7,1,2],[3,2,9,4,7],[8,9,4,2,3]]
[q+l[w+1][t+1] for w,i in enumerate(l[:-1]) for t,q in enumerate(i[:-1])]
then you can avoid using numpy :) and the output is
[7,12,11,8,12,6,11,7]
Is there a simpler and more memory efficient way to do the following in numpy alone.
import numpy as np
ar = np.array(a[l:r])
ar += c
a = a[0:l] + ar.tolist() + a[r:]
It may look primitive but it involves obtaining a subarray copy of the given array, then prepare two more copies of the same to append in left and right direction in addition to the scalar add. I was hoping to find some more optimized way of doing this. I would like a solution that is completely in Python list or NumPy array, but not both as converting from one form to another as shown above would cause serious overhead when the data is huge.
You can just do the assignment inplace as follows:
import numpy as np
a = np.array([1, 1, 1, 1, 1])
a[2:4] += 5
>>> a
array([1, 1, 6, 6, 1])
I'd like to use numpy to calculate the inverse. But I'm getting an error:
'numpy.ndarry' object has no attribute I
To calculate inverse of a matrix in numpy, say matrix M, it should be simply:
print M.I
Here's the code:
x = numpy.empty((3,3), dtype=int)
for comb in combinations_with_replacement(range(10), 9):
x.flat[:] = comb
print x.I
I'm presuming, this error occurs because x is now flat, thus 'I' command is not compatible. Is there a work around for this?
My goal is to print the INVERSE MATRIX of every possible numerical matrix combination.
The I attribute only exists on matrix objects, not ndarrays. You can use numpy.linalg.inv to invert arrays:
inverse = numpy.linalg.inv(x)
Note that the way you're generating matrices, not all of them will be invertible. You will either need to change the way you're generating matrices, or skip the ones that aren't invertible.
try:
inverse = numpy.linalg.inv(x)
except numpy.linalg.LinAlgError:
# Not invertible. Skip this one.
pass
else:
# continue with what you were doing
Also, if you want to go through all 3x3 matrices with elements drawn from [0, 10), you want the following:
for comb in itertools.product(range(10), repeat=9):
rather than combinations_with_replacement, or you'll skip matrices like
numpy.array([[0, 1, 0],
[0, 0, 0],
[0, 0, 0]])
Another way to do this is to use the numpy matrix class (rather than a numpy array) and the I attribute. For example:
>>> m = np.matrix([[2,3],[4,5]])
>>> m.I
matrix([[-2.5, 1.5],
[ 2. , -1. ]])
Inverse of a matrix using python and numpy:
>>> import numpy as np
>>> b = np.array([[2,3],[4,5]])
>>> np.linalg.inv(b)
array([[-2.5, 1.5],
[ 2. , -1. ]])
Not all matrices can be inverted. For example singular matrices are not Invertable:
>>> import numpy as np
>>> b = np.array([[2,3],[4,6]])
>>> np.linalg.inv(b)
LinAlgError: Singular matrix
Solution to singular matrix problem:
try-catch the Singular Matrix exception and keep going until you find a transform that meets your prior criteria AND is also invertable.
What about inv?
e.g.:
my_inverse_array = inv(my_array)
IDK if anyone already mentioned this but I want to point out that matrix_object. I and np.linalg.inv(matrix_object) don't give a true inverse. This has given me a lot of grief. It's true that for a matrix object m, np.dot(m, m.I) = an identity matrix, but np.dot(m.I, m) =/= I. Same goes for np.linalg.inv(I).
Be careful with that.