IIUC, Here is a way to do it with numpy
a[(a['height'] == 160) & (a['pet'] == 'cat')]
Which returns:
array([('Jim', 160, 'cat')],
dtype=[('name', '<U30'), ('height', '<i4'), ('pet', '<U30')])
If you want to get just the index at which the conditions are satisfied, use numpy.where:
np.where((a['height'] == 160) & (a['pet'] == 'cat'))
# (array([1]),)
Caveat:
That being said, numpy might not be the best tool for your purposes. To see why, consider what your array a looks like:
>>> a
array([('Tom', 188, 'dog'), ('Jim', 160, 'cat'), ('Alice', 160, 'fish'),
('Alice', 157, 'dog'), ('Greg', 180, 'cat')],
dtype=[('name', '<U30'), ('height', '<i4'), ('pet', '<U30')])
It's kind of hard to read...
Think about using pandas for organizing tabular data:
import pandas as pd
df = pd.DataFrame({'name':name, 'height':height, 'pet':pet})
>>> df
height name pet
0 188 Tom dog
1 160 Jim cat
2 160 Alice fish
3 157 Alice dog
4 180 Greg cat
>>> df.loc[(df.height==160) & (df['pet'] == 'cat')]
height name pet
1 160 Jim cat