2

I have a numpy array of one-hot vectors. I want to find the mode of these one-hot vectors. Note that this is not equivalent to finding the mode over the values.

e.g. for

x = [[0,0,0,1],
     [0,0,0,1],
     [0,0,1,0],
     [0,1,0,0],
     [1,0,0,0]]

assert vector_mode(x) == [0,0,0,1]
assert scipy.stats.mode(x) == [0,0,0,0]

What is the most efficient way to do this with numpy/scipy?

15
  • Why the extra set of parens? Commented Sep 7, 2017 at 18:18
  • I wanted my list brackets to line up. =c) Commented Sep 7, 2017 at 18:18
  • 1
    You'll probably end up having to lexsort it and find the longest run of equal rows. Commented Sep 7, 2017 at 18:25
  • 1
    The key here is that these are one-hot vectors. Makes life muuuuch easier. Commented Sep 7, 2017 at 18:26
  • 1
    While we're on the topic, I'd like to point out that scipy.stats.mode has a loop in it that compares every value found in the array to the entire array, which can cause surprisingly bad performance for an array with a lot of distinct values in it. For example, scipy.stats.mode(range(10**5)) is appallingly slow. Commented Sep 7, 2017 at 18:37

2 Answers 2

2

We are dealing with one-hot vectors as rows of the 2D input array. So, argmax of each row would be unique to each one-hot vector. Get those. Then, get their counts. Anyone of the rows with the max argmax count would be the desired mode row output. Let's pick the first off those with one more use of argmax and finally index into 2D input.

Hence, one implementation -

idx = np.argmax(x,1)
count = np.bincount(idx)
out = x[(idx==count.argmax()).argmax()]
Sign up to request clarification or add additional context in comments.

Comments

1

If your vectors are one-hot, you can just use argmax to get the index of the hotspot and compute the mode of those:

hot = np.argmax(x, axis=1)
mode = scipy.stats.mode(hot).mode

In this case, mode is 3, meaning that the most common vector has a hotspot in index 3.

If you want to reinstate this into a one-hot vector, you can do:

vec = np.zeros(4)
vec[mode] = 1

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.