我有一個包含“close_date”、“open_date”、“amount”、“sales_rep”的資料框。
| 銷售代表 | open_date(MM/DD/YYYY) | 關閉日期 | 數量 |
|---|---|---|---|
| 吉姆 | 1/01/2021 | 2/05/2021 | 3 |
| 吉姆 | 1/15/2021 | 4/06/2021 | 26 |
| 吉姆 | 2/01/2021 | 2/06/2021 | 7 |
| 吉姆 | 2/15/2021 | 3/14/2021 | 12 |
| 吉姆 | 3/01/2021 | 2021/4/22 | 13 |
| 吉姆 | 3/15/2021 | 2021/3/29 | 5 |
| 吉姆 | 4/01/2021 | 2021/4/20 | 17 |
| 鮑勃 | 1/01/2021 | 1/12/2021 | 23 |
| 鮑勃 | 1/15/2021 | 2/16/2021 | 12 |
| 鮑勃 | 2/01/2021 | 3/04/2021 | 4 |
| 鮑勃 | 2/15/2021 | 4/05/2021 | 23 |
| 鮑勃 | 3/01/2021 | 2021/3/24 | 12 |
| 鮑勃 | 3/15/2021 | 2021 年 4 月 15 日 | 7 |
| 鮑勃 | 4/01/2021 | 5/01/2021 | 20 |
我想創建一個列來告訴我未結金額。因此,如果我們選擇第二行,我們可以看到 opp 已于 2021 年 4 月 6 日關閉。我想知道在那之前有多少開放的 opps。因此,我會查看第 5 行的開放日期是否在 2021 年 6 月 4 日的關閉日期之前,以及第 5 行的關閉日期是否也在 2021 年 4 月 6 日之后。在這種情況下,我會將其添加到總和中。我還想將當前行值包含在總和中。這應該為資料框中的每個銷售代表完成。我在下表中填寫了預期值。
| 銷售代表 | open_date(MM/DD/YYYY) | 關閉日期 | 數量 | open_amount_sum |
|---|---|---|---|---|
| 吉姆 | 1/01/2021 | 2/05/2021 | 3 | 36(我通過添加 3、26 和 7 得到這個,因為它們是唯一符合條件的兩個值,而 3 因為它是該行的值。) |
| 吉姆 | 1/15/2021 | 4/06/2021 | 26 | 56 |
| 吉姆 | 2/01/2021 | 2/06/2021 | 7 | 33 |
| 吉姆 | 2/15/2021 | 3/14/2021 | 12 | 51 |
| 吉姆 | 3/01/2021 | 2021/4/22 | 13 | 13 |
| 吉姆 | 3/15/2021 | 2021/3/29 | 5 | 44 |
| 吉姆 | 4/01/2021 | 2021/4/20 | 17 | 30 |
| 鮑勃 | 1/01/2021 | 1/12/2021 | 23 | 23 |
| 鮑勃 | 1/15/2021 | 2/16/2021 | 12 | 39 |
| 鮑勃 | 2/01/2021 | 3/04/2021 | 4 | 39 |
| 鮑勃 | 2/15/2021 | 4/05/2021 | 23 | 50 |
| 鮑勃 | 3/01/2021 | 2021/3/24 | 12 | 42 |
| 鮑勃 | 3/15/2021 | 2021 年 4 月 15 日 | 7 | 27 |
| 鮑勃 | 4/01/2021 | 5/01/2021 | 20 | 20 |
uj5u.com熱心網友回復:
從評論中編輯@RJ 的解決方案更好。這里的格式略有不同
df['open_amount_sum'] = df.apply(
lambda x: df[
df['sales_rep'].eq(x['sales_rep']) &
df['open_date'].le(x['close_date']) &
df['close_date'].ge(x['close_date'])
]['amount'].sum(),
axis=1,
)
這是一個解決方案,但它很慢而且有點難看。絕對可以改進
import pandas as pd
import io
df = pd.read_csv(io.StringIO(
"""
sales_rep,open_date,close_date,amount
Jim,1/01/2021,2/05/2021,3
Jim,1/15/2021,4/06/2021,26
Jim,2/01/2021,2/06/2021,7
Jim,2/15/2021,3/14/2021,12
Jim,3/01/2021,4/22/2021,13
Jim,3/15/2021,3/29/2021,5
Jim,4/01/2021,4/20/2021,17
Bob,1/01/2021,1/12/2021,23
Bob,1/15/2021,2/16/2021,12
Bob,2/01/2021,3/04/2021,4
Bob,2/15/2021,4/05/2021,23
Bob,3/01/2021,3/24/2021,12
Bob,3/15/2021,4/15/2021,7
Bob,4/01/2021,5/01/2021,20
"""
))
sum_df = df.groupby('sales_rep').apply(
lambda g:
g['close_date'].apply(
lambda close:
g.loc[
g['open_date'].le(close) & g['close_date'].ge(close),
'amount'
].sum())
).reset_index(level=0)
df['close_sum'] = sum_df['close_date']
df
uj5u.com熱心網友回復:
在分組之前將資料幀合并到自身,然后過濾:
(df
.merge(df, on='sales_rep')
.query('open_date_y <= close_date_x<=close_date_y')
.loc(axis=1)['sales_rep', 'open_date_x', 'close_date_x', 'amount_x', 'amount_y']
.rename(columns=lambda col: col.removesuffix('_x'))
.rename(columns = {'amount_y' : 'open_sum_amount'})
.groupby(['sales_rep', 'open_date', 'close_date', 'amount'],
sort = False,
as_index = False)
.sum()
)
sales_rep open_date close_date amount open_sum_amount
0 Jim 2021-01-01 2021-02-05 3 36
1 Jim 2021-01-15 2021-04-06 26 56
2 Jim 2021-02-01 2021-02-06 7 33
3 Jim 2021-02-15 2021-03-14 12 51
4 Jim 2021-03-01 2021-04-22 13 13
5 Jim 2021-03-15 2021-03-29 5 44
6 Jim 2021-04-01 2021-04-20 17 30
7 Bob 2021-01-01 2021-01-12 23 23
8 Bob 2021-01-15 2021-02-16 12 39
9 Bob 2021-02-01 2021-03-04 4 39
10 Bob 2021-02-15 2021-04-05 23 50
11 Bob 2021-03-01 2021-03-24 12 42
12 Bob 2021-03-15 2021-04-15 7 27
13 Bob 2021-04-01 2021-05-01 20 20
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/361512.html
