首页 > 解决方案 > 删除负数和相应的正数 - Python

问题描述

我有付款表,并且可能会错误地提交付款,因此出于分析目的,我需要删除否定金额和实际付款(它是在否定金额之前提交的付款)。但是,负金额不一定会转为正金额。

用例 1:原始表:

在此处输入图像描述

预期结果:

在此处输入图像描述

但是,当几次付款错误完成时,我也有如下情况:用例 2:原始表。虽然,我几乎准备放弃这些用例。

在此处输入图像描述

预期结果:

在此处输入图像描述

我试图在 SQL 级别解决它,但这似乎是 SQL 的一项艰巨任务。我尝试过的所有 SQL 解决方案,取金额的模数,然后对 accountid 和 abs 值进行几组,我觉得这是正确的方向,但是,也许在 Python 世界中有更好的方法来做到这一点。


import numpy as np
import pandas as pd

data = {
    'id': ['1','2','3','4','5','6','7','8','9','10'],
    'accountid': ['1','1','1','1','1','2','2','2','2','2'],
    'amount': [5,5,5,5,-5,5,5,5,-15,5]
}
df = pd.DataFrame(data)

标签: pythonpandas

解决方案



import numpy as np
import pandas as pd

data = {
    'id': ['1','2','3','4','5','6','7','8','9','10'],
    'accountid': ['1','1','1','1','1','2','2','2','2','2'],
    'amount': [5,5,5,5,-5,5,5,5,-15,5]
}
df = pd.DataFrame(data)
def clean_df(df):
    df = df.copy()
    result = []
    g = df.groupby("accountid")
    
    for _, group in g:
        to_reduce = group[group.amount < 0].amount.abs().sum()
        to_drop = []
        group = group[group.amount > 0]
        for index, row in group[::-1].iterrows():
            if to_reduce > 0:
                if row.amount > to_reduce:
                    # update row in gorup
                    row.amount -= to_reduce
                    group.loc[group.index == index, "amount"] = row.amount
                    to_reduce = 0
                else:
                    to_reduce -= row.amount
                    to_drop.append(index)
            if to_reduce == 0:
                group = group.drop(to_drop)
                result.append(group)
                break
    return pd.concat(result)
clean_df(df)

# output
    id  accountid   amount
0   1   1   5
1   2   1   5
2   3   1   5
5   6   2   5

只有 accountid == 2 的情况:

    id  accountid   amount
0   1   2   5
1   2   2   5
2   3   2   5
3   4   2   -15
4   5   2   5


clean_df(df)

# oudput

id  accountid   amount
0   1   2   5

推荐阅读