To start, Iβll try:
def return_equals(*args): x=[] c=args[-1] for a in args: x.append(np.nonzero(np.in1d(a,c))[0]) return x
If I add d=np.array([1,0,4,3,0]) (it has only 1 match, and what is no match?)
then
return_equals(a,b,d,c)
gives:
[array([2, 4], dtype=int32), array([1, 3], dtype=int32), array([2], dtype=int32), array([0, 1], dtype=int32)]
Since the length of both the input and return arrays may vary, you really cannot vectorize the problem. That is, to perform the operation on all inputs, some special gymnastics is required. And if the number of arrays is small compared to their typical length, I would not worry about speed. Iterating several times is not expensive. It iterates over 100 values ββthat are expensive.
You could, of course, pass the keyword arguments to in1d .
It is not clear what you are trying to do with the sorted_by parameter. Is that something you could just as easily apply to arrays before passing them to this function?
List the version of this iteration:
[np.nonzero(np.in1d(x,c))[0] for x in [a,b,d,c]]
I can imagine how to combine arrays into one long one using in1d and then breaking it into subarrays. There is np.split , but this requires you to specify how many elements should be placed in each sublist. This means that somehow the number of matches for each argument is determined. Doing this without a loop can be tricky.
Parts for this (which still need to be packaged as a function):
args=[a,b,d,c] lens=[len(x) for x in args] abc=np.concatenate(args) C=np.cumsum(lens) I=np.nonzero(np.in1d(abc,c))[0] S=np.split(I,(2,4,5)) [S[0],S[1]-C[0],S[2]-C[1],S[3]-C[2]] I
(2,4,5) - the number of elements I between successive values ββof C , that is, the number of elements that correspond to each of a , b , ...