3

I am new to python and facing a problem in dealing with Matrices.

I have a matrix, let's 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 elements which are repeated the maximum number of times in a matrix. (In this case, it is 3).

So the expected result is,

B = [0 0 0 0; 3 3 3 0; 3 3 0 0;3 0 0 0]

It would be really helpful if anyone can help me with the python code for this.

ifconfig
  • 6,242
  • 7
  • 41
  • 65
Rohan Gupta
  • 35
  • 1
  • 4

4 Answers4

2

Get the most occurring number across the entire array using Scipy's mode with axis set to None. Compare that number against the input array to give us a mask, which could be used to set the rest to zeros by elementwise multiplication with the input array/most-occurring number or using np.where to do the choosing.

Thus, 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)

With np.where for array output -

out = np.where(A==most_occ_num,A,0)

Sample 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]])
Divakar
  • 218,885
  • 19
  • 262
  • 358
1
 ----------------------------------------------------
cs95
  • 379,657
  • 97
  • 704
  • 746
1

This is MATLAB syntax, not numpy:

A = [1 0 0 2; 3 3 3 2; 3 3 0 2; 3 4 4 4]

though 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 fold, finding that most frequent element, and then replacing all the others. Neither action depends on the matrix being 2d, or being matrix as opposed to 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 count, so we can fine the most frequent value with (unique requires the 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 use the scipy mode instead of unique. He's something of an expert in using unique. :)

Divakar's use of np.where may be the simplest way of performing the replace.

Just for the fun of it, here's a masked array 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 inplace 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]])
hpaulj
  • 221,503
  • 14
  • 230
  • 353
  • Thanks hpaulj, this was very helpful. I have been working with Matlab, and decided that I should try Python as well. Thanks for the support. – Rohan Gupta Jun 12 '17 at 11:53
0

First, flatten it:

flat = A.flatten[0]
# flat = [1, 0, 0, 2, .. ]

Then, find the mode of the list:

Finding the mode of a list

replace none modes:

B = A.copy()
B[B != mode] = 0
codelessbugging
  • 2,849
  • 1
  • 14
  • 19