mar*_*lli 5 python dataframe pandas
我有一个像这样的数据帧:
df = pd.DataFrame({
'val_a': [3, 3, 3, 2, 2, 2, 1, 1, 1],
'val_b': [3, np.nan, 2, 2, 2, 0, 1, np.nan, 0],
'quantity': [1, 4, 2, 8, 5, 7, 1, 4, 2]
})
Run Code Online (Sandbox Code Playgroud)
它看起来像这样:
| | val_a | val_b | quantity |
|---:|--------:|--------:|-----------:|
| 0 | 3 | 3 | 1 |
| 1 | 3 | nan | 4 |
| 2 | 3 | 2 | 2 |
| 3 | 2 | 2 | 8 |
| 4 | 2 | 2 | 5 |
| 5 | 2 | 0 | 7 |
| 6 | 1 | 1 | 1 |
| 7 | 1 | nan | 4 |
| 8 | 1 | 0 | 2 |
Run Code Online (Sandbox Code Playgroud)
它是由 订购的val_a
。我想quantity
对每个val_a
. 所以:
| | val_a | val_b | quantity |
|---:|--------:|--------:|-----------:|
| 0 | 3 | 3 | 1 |
| 1 | 3 | nan | 4 |
| 2 | 3 | 2 | 2 |
| 3 | 2 | 2 | 8 |
| 4 | 2 | 2 | 5 |
| 5 | 2 | 0 | 7 |
| 6 | 1 | 1 | 1 |
| 7 | 1 | nan | 4 |
| 8 | 1 | 0 | 2 |
Run Code Online (Sandbox Code Playgroud)
这使
| val_a | quantity |
|--------:|-----------:|
| 3 | 7 |
| 2 | 27 |
| 1 | 34 |
Run Code Online (Sandbox Code Playgroud)
然而,这是棘手的部分。
我想排除值val_b
大于 key 的行val_a
。我会用一个例子来澄清:
val_a
是3
,没有行的具有val_b
大于val_a
。所以当val_a
是的累计总数3
是7
;val_a
是2
,则行0具有val_b
大于2
。该行有quantity
1。所以,不包括该行,当val_a
是的累计总数2
是27 - 1
,即26
;val_a
是1
,则行0,2,3,4具有val_b
大于1
,。该行有quantity
1。所以,不包括该行,当val_a
是的累计总数1
是34 - 1 - 2 - 8 - 5
,即18
;这是所需的输出:
| val_a | quantity |
|--------:|-----------:|
| 3 | 7 |
| 2 | 26 |
| 1 | 18 |
Run Code Online (Sandbox Code Playgroud)
在 NumPy 的帮助下:
# sum without conditions
raw_sum = df.groupby("val_a", sort=False).quantity.sum().cumsum()
# comparing each `val_b` against each unique `val_a` via `gt.outer`
sub_mask = np.greater.outer(df.val_b.to_numpy(), df.val_a.unique())
# selecting values to subtract from `quantity` and summing per `val_a`
to_sub = (sub_mask * df.quantity.to_numpy()[:, np.newaxis]).sum(axis=0)
# subtracting from the raw sum
result = raw_sum - to_sub
Run Code Online (Sandbox Code Playgroud)
要得到
>>> result.reset_index()
val_a quantity
0 3 7
1 2 26
2 1 18
Run Code Online (Sandbox Code Playgroud)