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.