Question: I have the following data frame:  identifier loan_identifier cashflow_date cashflow_type amount 0 1 a111 15/07/2023 funding -195.71 1 2 a111 01/07/2023 interest_repayment 3.11 2 3 a111 15/07/2023 interest_repayment 0.04 3 4 a111 20/07/2023 interest_repayment 0.04 4 5 a111 11/06/2023 principal_repayment 195.33 5 6 b222 10/07/2023 funding -3915.45 6 13 b222 10/07/2023 interest_repayment 0.73 7 14 b222 10/07/2023 interest_repayment 0.73 8 15 b222 13/06/2023 principal_repayment 3906.50  cashflow_date of funding cashflow_type should be the earliest for each loan_identifier. Each row with cashflow_type != funding whose date is earlier than funding row of that loan_identifer should be set to funding cashflow_date. So the above dataframe should look like this:  identifier loan_identifier cashflow_date cashflow_type amount 0 1 a111 15/07/2023 funding -195.71 1 2 a111 15/07/2023 interest_repayment 3.11 2 3 a111 15/07/2023 interest_repayment 0.04 3 4 a111 20/07/2023 interest_repayment 0.04 4 5 a111 15/07/2023 principal_repayment 195.33 5 6 b222 10/07/2023 funding -3915.45 6 13 b222 10/07/2023 interest_repayment 0.73 7 14 b222 10/07/2023 interest_repayment 0.73 8 15 b222 10/07/2023 principal_repayment 3906.50  Here's the data as a dictionary: data = { 'identifier': {0: 1, 1: 2, 2: 3, 3: 4, 4: 5, 5: 6, 6: 13, 7: 14, 8: 15}, 'loan_identifier': {0: 'a111', 1: 'a111', 2: 'a111', 3: 'a111', 4: 'a111', 5: 'b222', 6: 'b222', 7: 'b222', 8: 'b222'}, 'cashflow_date': {0: '15/07/2023', 1: '01/07/2023', 2: '15/07/2023', 3: '20/07/2023', 4: '11/06/2023', 5: '10/07/2023', 6: '10/07/2023', 7: '10/07/2023', 8: '13/06/2023'}, 'cashflow_type': {0: 'funding', 1: 'interest_repayment', 2: 'interest_repayment', 3: 'interest_repayment', 4: 'principal_repayment', 5: 'funding', 6: 'interest_repayment', 7: 'interest_repayment', 8: 'principal_repayment'}, 'amount': {0: -195.71, 1: 3.11, 2: 0.04, 3: 0.04, 4: 195.33, 5: -3915.45, 6: 0.73, 7: 0.73, 8: 3906.5} }  How can I do this transformation using full advantage of pandas?

Answer: You can use boolean indexing: # ensure datetime df['cashflow_date'] = pd.to_datetime(df['cashflow_date'], dayfirst=True) # get rows with "funding" # NB. if more than one per ID, you need to drop duplicates m1 = df['cashflow_type'].eq('funding') # get reference date per ID ref = df['loan_identifier'].map(df.loc[m1].set_index('loan_identifier') ['cashflow_date']) # change if lower than reference m2 = df['cashflow_date'].lt(ref) df.loc[m2, 'cashflow_date'] = ref[m2]  Another approach with a custom groupby.apply and clip: df['cashflow_date'] = pd.to_datetime(df['cashflow_date'], dayfirst=True) df['cashflow_date'] = (df.groupby('loan_identifier', group_keys=False) .apply(lambda g: g['cashflow_date'] .clip(lower=g.loc[g['cashflow_type'].eq('funding'), 'cashflow_date'].min()) ) )  Output:  identifier loan_identifier cashflow_date cashflow_type amount 0 1 a111 2023-07-15 funding -195.71 1 2 a111 2023-07-15 interest_repayment 3.11 2 3 a111 2023-07-15 interest_repayment 0.04 3 4 a111 2023-07-20 interest_repayment 0.04 4 5 a111 2023-07-15 principal_repayment 195.33 5 6 b222 2023-07-10 funding -3915.45 6 13 b222 2023-07-10 interest_repayment 0.73 7 14 b222 2023-07-10 interest_repayment 0.73 8 15 b222 2023-07-10 principal_repayment 3906.50