You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Pandas DataFrame中从Last_dup=1的行检测近2个月费用变化

Solution to Detect Fee Changes Over Recent 2 Months per Policy ID

Got it, let's work through this problem together. The goal is to check if Fee1 or Fee2 changed in the 2 months prior to each row where Last_dup = 1 (per Policy_id), and mark those rows with Changed = 1 if a change occurred.

Step 1: Prepare the Data

First, we need to make sure our data is sorted correctly by Policy_id and Start_Date—this is critical for accurately comparing historical rows. We'll also convert date columns to datetime type to avoid sorting issues.

import pandas as pd

# Recreate your sample DataFrame
data = {
    'Id': [0,1,2,3,4,5,6],
    'Policy_id': ['b123','b123','b123','c123','c123','d123','d123'],
    'Start_Date': ['2019/02/24','2019/03/24','2019/04/24','2018/09/01','2018/10/01','2017/02/24','2017/03/24'],
    'End_Date': ['2019/03/23','2019/04/23','2019/05/23','2019/09/30','2019/10/31','2019/03/23','2019/04/23'],
    'Fee1': [0,0,10,10,10,0,0],
    'Fee2': [23,23,23,0,0,0,0],
    'Last_dup': [0,0,1,0,1,0,1]
}

df = pd.DataFrame(data)

# Convert date columns to datetime
df['Start_Date'] = pd.to_datetime(df['Start_Date'])

# Sort by Policy_id and Start_Date to ensure chronological order
df = df.sort_values(['Policy_id', 'Start_Date']).reset_index(drop=True)

Step 2: Option 1 - Intuitive Group-Based Approach

This method uses groupby to handle each Policy_id separately, making it easy to customize the回溯 logic if needed later.

def check_fee_changes(group):
    # Initialize Changed column to 0 for all rows
    group['Changed'] = 0
    
    # Find rows where Last_dup is 1 in the current group
    duplicate_rows = group[group['Last_dup'] == 1]
    
    for idx in duplicate_rows.index:
        # Get the previous 2 rows (representing the last 2 months)
        # Use max(0, idx-2) to avoid going out of bounds for the first rows
        previous_rows = group.loc[max(0, idx-2):idx-1, ['Fee1', 'Fee2']]
        
        if not previous_rows.empty:
            # Get current row's fees
            current_fees = group.loc[idx, ['Fee1', 'Fee2']]
            
            # Check if any previous row has different Fee1 or Fee2
            has_change = (~previous_rows.equals(current_fees)).any().any()
            
            # Mark as changed if difference exists
            if has_change:
                group.loc[idx, 'Changed'] = 1
    
    return group

# Apply the function to each Policy_id group
result_df = df.groupby('Policy_id', group_keys=False).apply(check_fee_changes)

# Revert to the original Id order to match your expected output
result_df = result_df.sort_values('Id').reset_index(drop=True)

print(result_df)

Step 3: Option 2 - Efficient Shift-Based Approach

If you're working with large datasets, this method is faster. It uses shift() to compare each row with the 1st and 2nd previous rows in the same group.

# Initialize Changed column to 0
df['Changed'] = 0

# Create masks to check if Fee1/Fee2 changed from the previous 1 or 2 rows
fee1_changed = df.groupby('Policy_id')['Fee1'].transform(lambda x: (x != x.shift(1)) | (x != x.shift(2)))
fee2_changed = df.groupby('Policy_id')['Fee2'].transform(lambda x: (x != x.shift(1)) | (x != x.shift(2)))

# Only mark rows where Last_dup = 1 and a fee change occurred
mask = df['Last_dup'] == 1
df.loc[mask, 'Changed'] = (fee1_changed | fee2_changed)[mask].astype(int)

# Revert to original Id order
df = df.sort_values('Id').reset_index(drop=True)

print(df)

Expected Output

Both methods will produce the exact result you're looking for:

Id Policy_id Start_Date   End_Date  Fee1  Fee2  Last_dup  Changed
0   0      b123 2019-02-24 2019-03-23     0    23         0        0
1   1      b123 2019-03-24 2019-04-23     0    23         0        0
2   2      b123 2019-04-24 2019-05-23    10    23         1        1
3   3      c123 2018-09-01 2019-09-30    10     0         0        0
4   4      c123 2018-10-01 2019-10-31    10     0         1        0
5   5      d123 2017-02-24 2019-03-23     0     0         0        0
6   6      d123 2017-03-24 2019-04-23     0     0         1        0

Notes

  • If a Policy_id has multiple rows with Last_dup = 1, both methods will handle each of them correctly.
  • The shift-based method is more efficient for large datasets, while the group-based method is easier to modify if you need to adjust the回溯 window (e.g., check 3 months instead of 2).

内容的提问来源于stack exchange,提问作者Soufiane Sabiri

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.12 04:56:34