We can also use groupby transform to see if there are any values in each group that eq r and use this Boolean index to then replace those values with r:
m = df['cat_col'].eq('r').groupby(df['group']).transform('any')
df.loc[m, 'cat_col'] = 'r'
Or conditionally replace nr with r using the same boolean index (in case there are multiple replace values):
m = df['cat_col'].eq('r').groupby(df['group']).transform('any')
df.loc[m, 'cat_col'] = df.loc[m, 'cat_col'].replace({'nr': 'r'})
df:
group cat_col
0 g1 r
1 g1 r
2 g1 r
3 g1 r
4 g2 nr
5 g2 nr
Boolean index steps in a DataFrame:
steps_df = pd.DataFrame({
# Find where cat_col is r
'step 1': df['cat_col'].eq('r'),
# Find groups which have an r value
'step 2': df['cat_col'].eq('r').groupby(df['group']).transform('any')
})
step 1 step 2
0 True True
1 False True
2 True True
3 False True
4 False False
5 False False
Setup (DataFrame and imports):
import pandas as pd
df = pd.DataFrame({
'group': ['g1', 'g1', 'g1', 'g1', 'g2', 'g2'],
'cat_col': ['r', 'nr', 'r', 'nr', 'nr', 'nr']
})