Q:

find column and row index on specific regex match on a pandas dataframe

Let's say I have a pandas dataframe with string content in its cells.
What's the best way to find a string that matches an specific regex and then return a list of tuples with their respective row and column indexes?
I.e.,
import pandas as pd
mydf = pd.DataFrame({'a':['hello', 'world'], 'b': ['hello', 'folks']})

def findIndex(mydf, regex):
    return regex_indexes

If I do: 
regex = r"hello"
findIndex(mydf, regex) # it'd return [(0,0), (0,1)],

If I do:
regex = r"matt"
findIndex(mydf, regex) # it'd return [(-1,-1)],

If I do:
regex = r"folks"
findIndex(mydf, regex) # it'd return [(1,1)], 

I could do a double for loop on the pd.DataFrame but was wondering if other ideas are better...

A:

You can try to use apply, str.match and nonzero.
def findIdx(df, pattern):
    return df.apply(lambda x: x.str.match(pattern)).values.nonzero()

findIdx(mydf, r"hello")
(array([0, 0]), array([0, 1]))

df.apply(lambda x: x.str.match(pattern)).values return an array of the same size of df where True indicates matches and False otherwise. 
We then use nonzero to find the indices of 1(True) part.

It will return the indices that match the pattern in a tuple of arrays. If you need 
a list of tuples, use list(zip(*findIdx(mydf, r"hello")))
[(0, 0), (0, 1)] 

or np.transpose(findIdx(mydf, r"hello")). 

If one needed to return None while nothing is found, one can try
def findIdx(df, pattern):
    ret = df.apply(lambda x: x.str.match(pattern)).values.nonzero()
    return None if len(ret[0]) == 0 else ret

Note: str.match uses re.match under the hook. It will match a string which begins with pattern in this example function. If one wants to find whether a string contains pattern as a substring, use str.contains rather than str.match.

