如何筛选特定条件数据并分Sheet导出?Excel数据处理求助
解决方案:用分组匹配替代基础循环,避免重复/遗漏
我之前也踩过用基础循环处理这种配对问题的坑——要么同一笔记录被重复匹配,要么漏掉了该配对的记录,逻辑越写越绕还容易出错。不如换成分组+批量匹配的思路,用Pandas来实现,不仅逻辑清晰,还能彻底解决重复和遗漏的问题。
先再明确下咱们的核心需求:
- 筛选同company、同product ID且Direction为BUY/SELL配对的数据
- 拆分两个输出Sheet:
- Sheet1:单个BUY记录和单个SELL记录的Amount完全相等的配对
- Sheet2:同company+product ID组内,BUY的总Amount等于SELL的总Amount的所有记录
步骤1:数据导入与预处理
先把原始数据读进来,只保留我们需要的列,顺便做下数据清洗:
import pandas as pd # 替换成你的原始文件路径 df = pd.read_excel("your_source_data.xlsx") # 只保留目标列,避免无关数据干扰 df = df[["company", "product ID", "Direction", "amount"]] # 清理空值(根据你的数据情况可选) df = df.dropna(subset=["company", "product ID", "Direction", "amount"]) # 确保amount是数值类型,避免后续计算出错 df["amount"] = pd.to_numeric(df["amount"], errors="coerce") df = df.dropna(subset=["amount"])
步骤2:处理Sheet1(单个金额相等的配对)
这里的关键是标记已匹配的记录,避免重复配对。我们按company+product ID分组,在每个组内拆分BUY和SELL的记录,然后逐一匹配相等的金额:
sheet1_records = [] # 按公司+产品ID分组遍历,确保只在同组内处理配对 for (company, prod_id), group in df.groupby(["company", "product ID"]): # 拆分当前组内的BUY和SELL子数据集 buy_rows = group[group["Direction"] == "BUY"].copy().reset_index(drop=True) sell_rows = group[group["Direction"] == "SELL"].copy().reset_index(drop=True) # 只有同时存在BUY和SELL的组才需要处理 if buy_rows.empty or sell_rows.empty: continue # 用布尔数组标记哪些行已经被匹配过 buy_matched = [False] * len(buy_rows) sell_matched = [False] * len(sell_rows) # 遍历每一行BUY,找未匹配的SELL中金额相等的记录 for i, buy_row in buy_rows.iterrows(): if buy_matched[i]: continue # 跳过已匹配的BUY记录 # 找到未匹配且金额相等的SELL记录 matched_sell_idx = sell_rows[(~sell_matched) & (sell_rows["amount"] == buy_row["amount"])].index if not matched_sell_idx.empty: # 取第一个匹配的SELL记录(如果有多个,后续循环会处理剩下的) j = matched_sell_idx[0] # 把配对的两条记录加入Sheet1列表 sheet1_records.append(buy_row.to_dict()) sheet1_records.append(sell_rows.loc[j].to_dict()) # 标记这两条记录为已匹配,避免重复使用 buy_matched[i] = True sell_matched[j] = True # 转换为DataFrame,方便导出 sheet1_df = pd.DataFrame(sheet1_records)
步骤3:处理Sheet2(组内总金额相等的记录)
如果你的需求是“整个组的BUY总金额等于SELL总金额”,那直接分组求和筛选即可:
# 计算每个组内BUY和SELL的总金额 group_total = df.groupby(["company", "product ID", "Direction"])["amount"].sum().unstack(fill_value=0) # 筛选出BUY和SELL总金额相等的组 valid_groups = group_total[group_total["BUY"] == group_total["SELL"]].index # 提取这些组的所有记录 sheet2_df = df[df.set_index(["company", "product ID"]).index.isin(valid_groups)]
如果你的需求是“多笔BUY的总和等于多笔SELL的总和”(而非整个组的总金额相等),这种场景逻辑会更复杂,需要用到组合求和的方式,要是你需要这种场景的实现,可以再补充说明细节~
步骤4:导出到Excel的两个Sheet
最后把两个结果导出到同一个Excel文件的不同Sheet:
with pd.ExcelWriter("final_result.xlsx") as writer: sheet1_df.to_excel(writer, sheet_name="Equal_Amount_Pairs", index=False) sheet2_df.to_excel(writer, sheet_name="Equal_Total_Groups", index=False)
为什么这个方法比基础循环靠谱?
- 分组隔离:确保我们只在同一个company+product ID的组内处理配对,不会出现跨组错误匹配的情况
- 已匹配标记:通过布尔数组明确标记已使用的记录,彻底避免重复配对
- Pandas批量操作:比手动逐行循环效率高得多,也减少了人为编写循环时容易出现的逻辑漏洞
内容的提问来源于stack exchange,提问作者Squirrelxd
相关产品推荐
相关产品推荐

