如何根据条件在df中减去列

2024-10-03 21:35:01 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个像这样的数据集。在我的新数据集中,我想用主列和余数列减去金额列

例如,如果amount列是4,principal列是2,remainder列是3,那么第一个金额列必须从第一个主列和第一个余数列中减去,第二个是第二个主列和第二个余数列,第三个是第三个余数列(因为现在没有更多的主列)。最后一列amount4必须保持与newamount4相同的状态

amount1  amount2   amount3 amount4  principal1  principal2  remainder1  remainder2    remainder3  
 100      250       150    100           250       100         80         100          100 
 200      200       350    25            450       100        120         100          50
 300      150       450    30            200       100        150         100          100
 250      550       550    100           100       200         50         500          200
 550      200       650    200          250       200        500         100          500

我的新数据集必须如下所示。请注意,am代表金额,pr代表本金,rem代表余额

newamount1          newamount2         newamount3     newamount4       
-230(am1-pr1-rem1)  50(am2-pr2-rem2)  50(am3-rem3)    amount4        
-370                0                 300             amount4        
 50                 50                350             amount4        
 100               -150               350             amount4        
-200               -100               150             amount4

Tags: 数据principal状态代表金额amountremainderamount1
1条回答
网友
1楼 · 发布于 2024-10-03 21:35:01

您可以使用defaultdict对常用后缀进行分组,然后应用缩减函数(np.subtract.reduce)以获得输出:

from collections import defaultdict

mapping = defaultdict(list)
for column in df:
    if column[-1] != 4:
        mapping[f"newamount{column[-1]}"].append(df[column])
    else:
        mapping[f"newamount{column[-1]}"].append(column)

mapping = {
    key: np.subtract.reduce(value) if "4" not in key else "amount4"
    for key, value in mapping.items()
}

pd.DataFrame(mapping)

    newamount1  newamount2  newamount3  newamount4
0   -230        50          50          amount4
1   -370        0           300         amount4
2   -50        -50          350         amount4
3   100       -150          350         amount4
4   -200     -100           150         amount4

您还可以通过groupby进行迭代:

mapping = {
    f"newamount{key}": frame.agg(np.subtract.reduce, axis=1)
    for key, frame in df.groupby(df.columns.str[-1], axis=1)
}

pd.DataFrame(mapping).assign(newamount4="amount4")

如果您的数据超出4,您可以使用下面的代码并进行调整:

在分组和聚合之前,可以使用来自pyjanitorpivot_longer函数来重塑数据;目前,您必须从github安装最新的开发版本:

 # install latest dev version
# pip install git+https://github.com/ericmjl/pyjanitor.git
 import janitor

(
    df.pivot_longer(names_to=".value", 
                    names_pattern=".+(\d)$", 
                    ignore_index=False)
    .fillna(0)
    .add_prefix("newamount")
    .groupby(level=0)
    .agg(np.subtract.reduce)
    .assign(newamount4="amount4") # edit your preferred column
)

仅在Pandas中使用函数,我们可以在分组和聚合之前通过堆叠来重塑数据:

df.columns = df.columns.str.split("(\d)", expand=True).droplevel(-1)
(
    df.stack(0)
    .fillna(0)
    .droplevel(-1)
    .groupby(level=0)
    .agg(np.subtract.reduce)
    .add_prefix("newamount")
    .assign(newamount4="amount4")
)

相关问题 更多 >