Python:对满足条件的列中的值求和

Python: sum values in column where condition is met

我有一个像这样的 DataFrame:

import pandas as pd

df=pd.DataFrame()
df['exchange'] = [1, 1, 1, 2, 3]
df['type'] = ['deposit', 'deposit', 'trade', 'deposit', 'deposit']
df['value'] = [10, 10, '30', '40', '100']

看起来像:

    exchange     type       value
 0  1            deposit    10
 1  1            deposit    10
 2  1            trade      30
 3  2            deposit    40
 4  3            deposit    100

我想在 "value" 列中添加元素,其中 "type"='deposit' 基于 "exchange" 和前向填充以获得如下内容:

    exchange     type       value   balance
 0  1            deposit    10      10
 1  1            deposit    10      20
 2  1            trade      30      20
 3  2            deposit    40      40
 4  3            deposit    100     100

其中 "balance" 是由 "exchange" 过滤的 deposits 的总和。

有没有办法在没有 for loops/if 语句的情况下以 python 方式执行此操作?

您可以先按“交换”分组,然后应用np.cumsum,最后分配type为“存款”的结果。

import pandas as pd
import numpy as np

df.loc[df["type"]=="deposit", "balance"] = df.loc[df["type"]=="deposit"].groupby("exchange", sort=False)["value"].apply(np.cumsum)

最后你可以用你提到的 forward-fill 填充缺失值。

df = df.fillna(method='ffill')

您可以使用groupby + cumsum填写“余额”栏;这也填充了“交易”,因此您 mask 取决于 type 的结果是否为“存款”,如果不是“存款”,则使用 ffill 进行前向填充:

df['value'] = df['value'].astype(int)
df['balance'] = df['value'].mask(df['type']!='deposit').groupby(df['exchange']).cumsum().ffill()

输出:

   exchange     type  value  balance
0         1  deposit     10     10.0
1         1  deposit     10     20.0
2         1    trade     30     20.0
3         2  deposit     40     40.0
4         3  deposit    100    100.0

您使用 whereNaN 非存款行,然后在每个交换组中使用 expanding sum,因为它认为 NaN 0 时求和,这样它就可以按照你的意愿向前填充。

df['balance'] = (df['value'].where(df['type'].eq('deposit'))
                   .groupby(df['exchange'])
                   .expanding().sum()
                   .reset_index(0, drop=True))

   exchange     type  value  balance
0         1  deposit     10     10.0
1         1  deposit     10     20.0
2         1    trade     30     20.0
3         2  deposit     40     40.0
4         3  deposit    100    100.0