Working with matrices in Python
I am new to python and am facing a problem when working with matrices.
I have a matrix say
A = [1 0 0 2; 3 3 3 2; 3 3 0 2; 3 4 4 4]
Now I want to make all the elements in the matrix equal to zero, except for the elements that are repeated the maximum number of times in the matrix. (In this case, it is 3).
So the expected output is:
B = [0 0 0 0; 3 3 3 0; 3 3 0 0;3 0 0 0]
It would be very helpful if someone could help me with the python code for this.
source to share
This is MATLAB syntax, not numpy:
A = [1 0 0 2; 3 3 3 2; 3 3 0 2; 3 4 4 4]
although np.matrix
emulates it with:
In [172]: A = np.matrix('1 0 0 2; 3 3 3 2; 3 3 0 2; 3 4 4 4')
In [173]: A
Out[173]:
matrix([[1, 0, 0, 2],
[3, 3, 3, 2],
[3, 3, 0, 2],
[3, 4, 4, 4]])
Your task is 2 times, to find this most frequently used element, and then replace all the others. No action depends on whether the matrix is ββ2d, or is matrix
unlike an array.
In [174]: A1=A.A1
In [175]: A1
Out[175]: array([1, 0, 0, 2, 3, 3, 3, 2, 3, 3, 0, 2, 3, 4, 4, 4])
np.unique
can give us the frequency, so we can estimate the most common value c ( unique
requires 1d):
In [179]: u,c = np.unique(A1, return_counts=True)
In [180]: u
Out[180]: array([0, 1, 2, 3, 4])
In [181]: c
Out[181]: array([3, 1, 3, 6, 3])
In [182]: np.argmax(c)
Out[182]: 3
In [183]: u[np.argmax(c)]
Out[183]: 3
I'm surprised that Divakar uses scipy
mode
instead unique
. He's kind of an expert in usage unique
. :)
Using Divakar np.where
may be the easiest way to perform replacement.
Just for fun, here's an array masked approach:
In [196]: np.ma.MaskedArray(A, A!=3)
Out[196]:
masked_matrix(data =
[[-- -- -- --]
[3 3 3 --]
[3 3 -- --]
[3 -- -- --]],
mask =
[[ True True True True]
[False False False True]
[False False True True]
[False True True True]],
fill_value = 999999)
In [197]: _.filled(0)
Out[197]:
matrix([[0, 0, 0, 0],
[3, 3, 3, 0],
[3, 3, 0, 0],
[3, 0, 0, 0]])
Or an in-place change:
In [199]: A[A!=3] = 0
In [200]: A
Out[200]:
matrix([[0, 0, 0, 0],
[3, 3, 3, 0],
[3, 3, 0, 0],
[3, 0, 0, 0]])
source to share
Get the most opposing number across the entire array using Scipy mode
c axis
, set to None
. Compare this number with the input array to give us a mask that can be used to set the remainder to zeros by multiplying the elements by the input array / most common number or using np.where
to select.
So one approach would be -
from scipy.stats import mode
most_occ_num = mode(A, axis=None)[0][0]
out = most_occ_num*(A==most_occ_num)
C np.where
to output an array -
out = np.where(A==most_occ_num,A,0)
Example run -
In [129]: A = np.matrix([[1, 0 ,0 ,2],[ 3, 3, 3, 2],[ 3 ,3 ,0 ,2],[ 3 ,4 ,4 ,4]])
In [140]: A
Out[140]:
matrix([[1, 0, 0, 2],
[3, 3, 3, 2],
[3, 3, 0, 2],
[3, 4, 4, 4]])
In [141]: most_occ_num = mode(A, axis=None)[0][0]
In [142]: most_occ_num*(A==most_occ_num)
Out[142]:
matrix([[0, 0, 0, 0],
[3, 3, 3, 0],
[3, 3, 0, 0],
[3, 0, 0, 0]])
In [143]: np.where(A==most_occ_num,A,0)
Out[143]:
array([[0, 0, 0, 0],
[3, 3, 3, 0],
[3, 3, 0, 0],
[3, 0, 0, 0]])
source to share