3

Although similar questions have been raised a couple of times, still I cannot make a function similar to the matlab ismember function in Python. In particular, I want to use this function in a loop, and compare in each iteration a whole matrix to an element of another matrix. Where the same value is occurring, I want to print 1 and in any other case 0.

Let say that I have the following matrices

d = np.reshape(np.array([ 2.25,  1.25,  1.5 ,  1.  ,  0.  ,  1.25,  1.75,  0.  ,  1.5 ,  0.  ]),(1,10))
d_unique = np.unique(d)

then I have

d_unique
array([ 0.  ,  1.  ,  1.25,  1.5 ,  1.75,  2.25])

Now I want to iterate like

J = np.zeros(np.size(d_unique))
for i in xrange(len(d_unique)):
        J[i] = np.sum(ismember(d,d_unique[i]))

so as to take as an output:

J = [3,1,2,2,1,1]

Does anybody have any idea? Many thanks in advance.

4

4 Answers 4

15

In contrast to other answers, numpy has the built-in numpy.in1d for doing that.

Usage in your case:

bool_array = numpy.in1d(array1, array2)

Note: It also accepts lists as inputs.

EDIT (2021): numpy now recommend using np.isin instead of np.in1d. np.isin preserves the shape of the input array, while np.in1d returns a flattened output.

Sign up to request clarification or add additional context in comments.

3 Comments

It gives bool not index
@Zanam, matlab API also returns Boolean vector for ismember. Moreover, setting ismember=np.in1d and executing the code of the question, results with the correct answer.
@YuvalAtzmon the matlab function has a second (optional) output which returns the location, which appears to be of interest to the OP.
2

To answer your question, I guess you could define a ismember similarly to:

def ismember(d, k):
  return [1 if (i == k) else 0 for i in d]

But I am not familiar with numpy, so a little adjustement may be in order.

I guess you could also use Counter from collections:

>>> from collections import Counter
>>> a = [2.25,  1.25,  1.5,  1.,  0.,  1.25,  1.75,  0.,  1.5,  0. ]
>>> Counter(a)
Counter({0.0: 3, 1.25: 2, 1.5: 2, 2.25: 1, 1.0: 1, 1.75: 1})
>>> Counter(a).keys()
[2.25, 1.25, 0.0, 1.0, 1.5, 1.75]
>>> c =Counter(a)
>>> [c[i] for i in sorted(c.keys())]
[3, 1, 2, 2, 1, 1]

Once again, not numpy, you will probably have to do some list(d) somewhere.

2 Comments

Thanks a lot, it works really nice with your second example. The first example is exactly what I was trying to do but at the end I had the following warning : "ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()". I cannot understand what this could mean.
@gioR When trying with your code, I have to use d[0] and not simply d
0

Try the following function:

def ismember(A, B):
    return [ np.sum(a == B) for a in A ]

This should very much behave like the corresponding MALTAB function.

2 Comments

Oh, it was extremely simple at the end. However, why numpy does not compare the numbers one by one? When I was trying to iterate through the whole matrix I had the following warning: 'ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()'
numpy has a built in function for that, why use list comprehension which is slow? I added an answer below.
0

Try the ismember library from pypi.

pip install ismember

Example:

# Import library
from ismember import ismember

# data
d = [ 2.25,  1.25,  1.5 ,  1.  ,  0.  ,  1.25,  1.75,  0.  ,  1.5 ,  0.  ]
d_unique = [ 0.  ,  1.  ,  1.25,  1.5 ,  1.75,  2.25]

# Lookup
Iloc,idx = ismember(d, d_unique)
 
# Iloc is boolean defining existence of d in d_unique
print(Iloc)
# [[True  True  True  True  True  True  True  True  True  True]]

# indexes of d_unique that exists in d
print(idx)
# array([5, 2, 3, 1, 0, 2, 4, 0, 3, 0], dtype=int64)

print(d_unique[idx])
array([2.25, 1.25, 1.5 , 1.  , 0.  , 1.25, 1.75, 0.  , 1.5 , 0.  ])

print(d[Iloc])
array([2.25, 1.25, 1.5 , 1.  , 0.  , 1.25, 1.75, 0.  , 1.5 , 0.  ])

# These vectors will match
d[Iloc]==d_unique[idx]

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.