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

技术求助:如何从DataFrame中移除负值及等额同用户正值?

解决方案

针对你遇到的用户退货负值记录与等额正值记录抵消的需求,用Python的Pandas可以高效处理,以下是具体实现步骤:

1. 数据预处理

首先将原始数据加载为DataFrame,并把带$符号的金额转换为数值类型,方便后续计算:

import pandas as pd

# 加载示例数据
data = {
    'Person': ['Person 1', 'Person 1', 'Person 1', 'Person 2', 'Person 2', 'Person 3', 'Person 3'],
    'Amount': ['$150', '-$150', '$150', '$100', '-$100', '$50', '$20']
}
df = pd.DataFrame(data)

# 去除金额中的$符号并转为数值
df['Amount'] = df['Amount'].str.replace('$', '').astype(float)

2. 分组抵消正负记录

针对每个用户的交易记录,统计等额正负交易的数量,保留抵消后剩余的正值记录:

def process_user(group):
    # 按金额绝对值分组,统计正负交易的数量
    amount_summary = group.groupby(group['Amount'].abs())['Amount'].agg(
        positive_count=lambda x: (x > 0).sum(),
        negative_count=lambda x: (x < 0).sum()
    )
    # 计算每个金额绝对值需要保留的正值数量
    amount_summary['remaining'] = amount_summary['positive_count'] - amount_summary['negative_count']
    
    # 收集需要保留的记录
    remaining_records = []
    for abs_amount, row in amount_summary.iterrows():
        if row['remaining'] > 0:
            # 提取对应数量的正值记录
            keep_rows = group[group['Amount'] == abs_amount].head(row['remaining'])
            remaining_records.append(keep_rows)
    return pd.concat(remaining_records)

# 对每个用户分组处理
result_df = df.groupby('Person').apply(process_user).reset_index(drop=True)

# 将金额转回带$的格式
result_df['Amount'] = '$' + result_df['Amount'].astype(str)

# 输出结果
print(result_df)

运行后得到的结果就是你期望的DataFrame:

Person Amount
0  Person 1   $150
1  Person 3    $50
2  Person 3    $20

备选方案(按交易顺序抵消)

如果需要严格按照交易顺序,用先出现的正值抵消后续的负值,可以用以下方法:

def process_user_by_order(group):
    # 分离正负交易记录
    positives = group[group['Amount'] > 0].copy()
    negatives = group[group['Amount'] < 0].copy()
    negatives['abs_amount'] = negatives['Amount'].abs()
    
    # 逐个匹配抵消
    for neg_idx, neg_row in negatives.iterrows():
        # 找到第一个金额匹配的未抵消正值
        match_pos = positives[positives['Amount'] == neg_row['abs_amount']].head(1)
        if not match_pos.empty:
            # 移除匹配的正负记录
            positives = positives.drop(match_pos.index)
            group = group.drop([neg_idx, match_pos.index[0]])
    return group

# 应用处理并格式化
result_df_order = df.groupby('Person').apply(process_user_by_order).reset_index(drop=True)
result_df_order['Amount'] = '$' + result_df_order['Amount'].astype(str)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.09 22:50:21