You can use the following vectorized approach:
In [191]: [tuple(x) for x in indices.reset_index().values]
Out[191]: [(0, 0), (1, 1), (2, 0)]
In [192]: data[0].str.extractall(r'(.)') \
.loc[[tuple(x) for x in indices.reset_index().values]]
Out[192]:
0
match
0 0 a
1 1 c
2 0 d
In [193]: data[0].str.extractall(r'(.)') \
.loc[[tuple(x) for x in indices.reset_index().values]] \
.reset_index(level=1, drop=True)
Out[193]:
0
0 a
1 c
2 d
Explanation:
In [194]: data[0].str.extractall(r'(.)')
Out[194]:
0
match
0 0 a
1 b
2 c
1 0 s
1 c
2 b
2 0 d
1 v
2 b
In [195]: data[0].str.extractall(r'(.)').loc[ [ (0,0), (1,1) ] ]
Out[195]:
0
match
0 0 a
1 1 c
Numpy solution:
In [259]: a = np.array([list(x) for x in data.values.reshape(1, len(data))[0]])
In [260]: a
Out[260]:
array([['a', 'b', 'c'],
['s', 'c', 'b'],
['d', 'v', 'b']],
dtype='<U1')
In [263]: pd.Series(a[np.arange(len(data)), indices])
Out[263]:
0 a
1 c
2 d
dtype: object