使用Pandas基于动态阈值表实现销售收入拆分的方法问询
Pandas基于动态阈值表实现销售收入拆分的方法问询
嘿,我来帮你梳理下怎么用Pandas搞定这个动态阈值下的销售收入拆分问题!首先得明确你的核心需求:根据随时间更新的阈值规则,判断每一笔销售的USD/AUD收入是否达到对应档位的阈值,然后匹配Party A和B的拆分比例对吧?先把你给出的阈值表整理成清晰的格式:
| Effective date | revenue threshold (USD) | revenue threshold (AUD) | Party A Split% | Party B Split% |
|---|---|---|---|---|
| 1-1-2024 | 100 | 50% | 50% | |
| 1-1-2024 | 200 | 80% | 20% | |
| 12-12-2025 | 100 | 150 | 50% | 50% |
| 12-12-2025 | 300 | 70% | 30% | |
| 12-12-2025 | 300 | 450 | 90% | 10% |
从这个表能看出来,规则是按生效日期划分阶段,每个阶段内有多个阶梯阈值——只要销售收入满足任一币种的阈值档位,就用对应的拆分比例,且高阈值档位优先(比如USD达到300的话,就用90/10的比例,而不是50/50)。接下来咱们一步步实现:
第一步:预处理阈值表
首先得把数据转成Pandas能方便处理的格式,比如日期转成datetime类型,百分比转成小数,空阈值设为无穷大(表示这个档位不触发该币种的阈值),还要按生效日期升序、阈值降序排序,确保高阈值优先匹配:
import pandas as pd # 构建你的阈值表(如果是从文件读取,用pd.read_csv/pd.read_excel即可) threshold_data = { "Effective date": ["1-1-2024", "1-1-2024", "12-12-2025", "12-12-2025", "12-12-2025"], "revenue threshold (USD)": [100, 200, 100, None, 300], "revenue threshold (AUD)": [None, None, 150, 300, 450], "Party A Split%": ["50%", "80%", "50%", "70%", "90%"], "Party B Split%": ["50%", "20%", "50%", "30%", "10%"] } threshold_df = pd.DataFrame(threshold_data) # 日期转datetime格式 threshold_df["Effective date"] = pd.to_datetime(threshold_df["Effective date"], format="%d-%m-%Y") # 空阈值设为无穷大,方便后续判断 threshold_df["revenue threshold (USD)"] = threshold_df["revenue threshold (USD)"].fillna(float("inf")) threshold_df["revenue threshold (AUD)"] = threshold_df["revenue threshold (AUD)"].fillna(float("inf")) # 百分比转小数,方便计算 threshold_df["Party A Split"] = threshold_df["Party A Split%"].str.replace("%", "").astype(float) / 100 threshold_df["Party B Split"] = threshold_df["Party B Split%"].str.replace("%", "").astype(float) / 100 # 排序:生效日期从早到晚,同日期下阈值从高到低,确保高阈值先被匹配 threshold_df = threshold_df.sort_values( by=["Effective date", "revenue threshold (USD)", "revenue threshold (AUD)"], ascending=[True, False, False] )
第二步:预处理销售表
同样把销售日期转成datetime类型,这里我模拟了一份销售表,你可以替换成自己的真实数据:
# 模拟销售表(替换成你的真实数据) sales_data = { "Sale Date": ["15-06-2024", "01-01-2026", "10-12-2025", "20-12-2025"], "Revenue (USD)": [150, 350, 90, 250], "Revenue (AUD)": [200, 500, 140, 400] } sales_df = pd.DataFrame(sales_data) sales_df["Sale Date"] = pd.to_datetime(sales_df["Sale Date"], format="%d-%m-%Y")
第三步:匹配每笔销售对应的生效阈值阶段
咱们需要给每一笔销售找到对应日期范围内生效的阈值规则——也就是找到销售日期之前或当天的最新生效日期:
# 获取所有唯一的生效日期并排序 effective_dates = sorted(threshold_df["Effective date"].unique()) # 给每笔销售匹配对应的生效阈值日期 sales_df["Effective Threshold Date"] = sales_df["Sale Date"].apply( lambda x: max([d for d in effective_dates if d <= x]) )
第四步:匹配对应的拆分比例并计算拆分金额
把销售表和阈值表合并,然后判断每笔销售是否满足阈值条件,取第一个满足条件的高阈值档位,最后计算拆分金额:
# 合并销售表和阈值表,得到对应生效日期下的所有阈值档位 merged_df = sales_df.merge(threshold_df, left_on="Effective Threshold Date", right_on="Effective date", how="left") # 判断是否满足当前阈值档位的条件:USD达标 或 AUD达标 merged_df["Meets Threshold"] = (merged_df["Revenue (USD)"] >= merged_df["revenue threshold (USD)"]) | (merged_df["Revenue (AUD)"] >= merged_df["revenue threshold (AUD)"]) # 按每笔销售分组,取第一个满足条件的档位(因为阈值降序,第一个就是最高档位) # 如果没有满足任何阈值的情况,就取该阶段的最低阈值档位(你可以根据需求调整逻辑) result_df = merged_df.groupby("Sale Date").apply( lambda g: g[g["Meets Threshold"]].head(1) if not g[g["Meets Threshold"]].empty else g.head(1) ).reset_index(drop=True) # 计算拆分后的收入(这里按USD计算,你可以根据需求换成AUD或统一币种) result_df["Party A Revenue (USD)"] = result_df["Revenue (USD)"] * result_df["Party A Split"] result_df["Party B Revenue (USD)"] = result_df["Revenue (USD)"] * result_df["Party B Split"] # 整理成最终的结果表 final_result = result_df[ ["Sale Date", "Revenue (USD)", "Revenue (AUD)", "Party A Split%", "Party B Split%", "Party A Revenue (USD)", "Party B Revenue (USD)"] ] print(final_result)
关键逻辑说明
- 高阈值优先:通过排序确保同生效日期下,高阈值的档位排在前面,这样匹配时会优先用最高档位的比例
- 动态日期匹配:通过
apply找到每笔销售对应的最新生效阈值规则,确保阈值更新后自动生效 - 灵活调整:如果你的阈值逻辑是“必须同时满足USD和AUD阈值”,只需要把
|换成&即可;如果低于所有阈值时不需要拆分,也可以修改分组后的逻辑
备注:内容来源于stack exchange,提问作者Crystal Kwan
相关产品推荐
相关产品推荐

