Here's a long way to solve this, to illustrate how groupby works.
Begin by creating a function which tests for the string you want:
def contains_str(x, string = '_Lh'):
    if string in x:
        return True
    else:
        return False
Next, iterate over your groups and apply this function:
keep_dict = {}
for label, group_df in df.groupby('col1'):
    keep = group_df['col2'].apply(contains_str).any()
    keep_dict[label] = keep
print(keep_dict)
# {'G1': True, 'G2': False, 'G3': False, 'G4': True}
Feel free to print individual items in the operation to understand their role.
Finally, map that dictionary to your current df:
df_final = df[df['col1'].map(keep_dict)].reset_index(drop=True)
    col1    col2
0   G1      OP2
1   G1      OP0
2   G1      OPP
3   G1      OPL_Lh
4   G4      TUI
5   G4      TYUI
6   G4      TR_Lh
You can condense these steps using the following code:
keep_dict = df.groupby('col1', as_index=True)['col2'].apply(lambda arr: any([contains_str(x) for x in arr])).to_dict()
print(keep_dict)
# {'G1': True, 'G2': False, 'G3': False, 'G4': True}
I hope this both answers your Q and explains what's taking place "behind the scenes" in groupby operations.