Python 将条件应用于组并仅填充新列的某些行

Python 将条件应用于组并仅填充新列的某些行,python,python-3.x,pandas,dataframe,Python,Python 3.x,Pandas,Dataframe,我有一个按WeekStartDt和WeekEndDt分组的数据帧(周不包括周六和周日)。数据框按每周组的金额降序排列。我每周按行数列对各组进行排名。BusDt列中的日期是根据“交易日期”分配的最高金额。第二高的金额应分配给BusDt+1。与其他交易日期对应的金额应更改为0 我尝试将transform函数与max一起使用来实现这一点,但这会在所有行中添加最高数量的值。我不知道如何在这里使用条件转换。任何帮助都将不胜感激。提前谢谢 输入数据帧 所需输出 df_group['NewAmt']=df_g

我有一个按WeekStartDt和WeekEndDt分组的数据帧(周不包括周六和周日)。数据框按每周组的
金额
降序排列。我每周按
行数
列对各组进行排名。
BusDt
列中的日期是根据“交易日期”分配的最高金额。第二高的金额应分配给
BusDt+1
。与其他
交易日期
对应的
金额
应更改为0

我尝试将transform函数与max一起使用来实现这一点,但这会在所有行中添加最高数量的值。我不知道如何在这里使用条件转换。任何帮助都将不胜感激。提前谢谢

输入数据帧 所需输出
df_group['NewAmt']=df_group.groupby(['WeekStartDt','WeekEndDt'])['Amount'].transform('max'))

我使用了groupby和transform,以及两个辅助变量

records = [{'Row_Num': 1,
  'Amount': 349282,
  'Transaction_Date': ' 2020-02-17       ',
  'WeekStartDt': ' 2020-02-17  ',
  'WeekEndDt': ' 2020-02-21 ',
  'BusDt': ' 2020-02-19 '},
 {'Row_Num': 2,
  'Amount': 15440,
  'Transaction_Date': ' 2020-02-18       ',
  'WeekStartDt': ' 2020-02-17  ',
  'WeekEndDt': ' 2020-02-21 ',
  'BusDt': ' 2020-02-19 '},
 {'Row_Num': 3,
  'Amount': 6636,
  'Transaction_Date': ' 2020-02-19       ',
  'WeekStartDt': ' 2020-02-17  ',
  'WeekEndDt': ' 2020-02-21 ',
  'BusDt': ' 2020-02-19 '},
 {'Row_Num': 4,
  'Amount': 6624,
  'Transaction_Date': ' 2020-02-20       ',
  'WeekStartDt': ' 2020-02-17  ',
  'WeekEndDt': ' 2020-02-21 ',
  'BusDt': ' 2020-02-19 '},
 {'Row_Num': 5,
  'Amount': -1526,
  'Transaction_Date': ' 2020-02-21       ',
  'WeekStartDt': ' 2020-02-17  ',
  'WeekEndDt': ' 2020-02-21 ',
  'BusDt': ' 2020-02-19 '},
 {'Row_Num': 1,
  'Amount': 502387,
  'Transaction_Date': ' 2020-02-24       ',
  'WeekStartDt': ' 2020-02-24  ',
  'WeekEndDt': ' 2020-02-28 ',
  'BusDt': ' NaT        '},
 {'Row_Num': 2,
  'Amount': 27637,
  'Transaction_Date': ' 2020-02-25       ',
  'WeekStartDt': ' 2020-02-24  ',
  'WeekEndDt': ' 2020-02-28 ',
  'BusDt': ' NaT        '},
 {'Row_Num': 3,
  'Amount': 9736,
  'Transaction_Date': ' 2020-02-26       ',
  'WeekStartDt': ' 2020-02-24  ',
  'WeekEndDt': ' 2020-02-28 ',
  'BusDt': ' NaT        '},
 {'Row_Num': 4,
  'Amount': 6671,
  'Transaction_Date': ' 2020-02-27       ',
  'WeekStartDt': ' 2020-02-24  ',
  'WeekEndDt': ' 2020-02-28 ',
  'BusDt': ' NaT        '},
 {'Row_Num': 5,
  'Amount': 5807,
  'Transaction_Date': ' 2020-02-28       ',
  'WeekStartDt': ' 2020-02-24  ',
  'WeekEndDt': ' 2020-02-28 ',
  'BusDt': ' NaT        '},
 {'Row_Num': 1,
  'Amount': 238532,
  'Transaction_Date': ' 2020-03-02       ',
  'WeekStartDt': ' 2020-03-02  ',
  'WeekEndDt': ' 2020-03-06 ',
  'BusDt': ' 2020-03-04 '},
 {'Row_Num': 2,
  'Amount': 21399,
  'Transaction_Date': ' 2020-03-03       ',
  'WeekStartDt': ' 2020-03-02  ',
  'WeekEndDt': ' 2020-03-06 ',
  'BusDt': ' 2020-03-04 '},
 {'Row_Num': 3,
  'Amount': 5837,
  'Transaction_Date': ' 2020-03-04       ',
  'WeekStartDt': ' 2020-03-02  ',
  'WeekEndDt': ' 2020-03-06 ',
  'BusDt': ' 2020-03-04 '},
 {'Row_Num': 4,
  'Amount': 5683,
  'Transaction_Date': ' 2020-03-05       ',
  'WeekStartDt': ' 2020-03-02  ',
  'WeekEndDt': ' 2020-03-06 ',
  'BusDt': ' 2020-03-04 '},
 {'Row_Num': 5,
  'Amount': 5670,
  'Transaction_Date': ' 2020-03-06       ',
  'WeekStartDt': ' 2020-03-02  ',
  'WeekEndDt': ' 2020-03-06 ',
  'BusDt': ' 2020-03-04 '},
 {'Row_Num': 1,
  'Amount': 740786,
  'Transaction_Date': ' 2020-03-09       ',
  'WeekStartDt': ' 2020-03-09  ',
  'WeekEndDt': ' 2020-03-13 ',
  'BusDt': ' NaT        '},
 {'Row_Num': 2,
  'Amount': 71530,
  'Transaction_Date': ' 2020-03-10       ',
  'WeekStartDt': ' 2020-03-09  ',
  'WeekEndDt': ' 2020-03-13 ',
  'BusDt': ' NaT        '},
 {'Row_Num': 3,
  'Amount': 6713,
  'Transaction_Date': ' 2020-03-11       ',
  'WeekStartDt': ' 2020-03-09  ',
  'WeekEndDt': ' 2020-03-13 ',
  'BusDt': ' NaT        '},
 {'Row_Num': 4,
  'Amount': 5648,
  'Transaction_Date': ' 2020-03-12       ',
  'WeekStartDt': ' 2020-03-09  ',
  'WeekEndDt': ' 2020-03-13 ',
  'BusDt': ' NaT        '},
 {'Row_Num': 5,
  'Amount': 5571,
  'Transaction_Date': ' 2020-03-13       ',
  'WeekStartDt': ' 2020-03-09  ',
  'WeekEndDt': ' 2020-03-13 ',
  'BusDt': ' NaT        '}]

df = pd.DataFrame(records)
df[['Transaction_Date', 'WeekStartDt', 'WeekEndDt', 'BusDt']] = df[['Transaction_Date', 'WeekStartDt', 'WeekEndDt', 'BusDt']].apply(pd.to_datetime, errors='coerce')
df['NewAmt1'] = df['BusDt'].eq(df['Transaction_Date']) * df.groupby('WeekEndDt')['Amount'].transform(max)
df['NewAmt2'] = df['BusDt'].add(pd.Timedelta(days=1)).eq(df['Transaction_Date']) * df.groupby('WeekEndDt')['Amount'].transform(lambda x: x.nlargest(2).iloc[1])
df['NewAmt'] = df[['NewAmt1', 'NewAmt2']].sum(axis=1)
df

对最大值使用一个
变换
,对第二大值使用另一个变换。将它们传递给
np。选择

m = df.TransactionDate == df.BusDt
m1 = m.groupby([df.WeekStartDt, df.WeekEndDt]).shift(fill_value=False)
grps = df.groupby(['WeekStartDt', 'WeekEndDt'])
s_1st = grps['Amount'].transform('max')
s_2nd = grps['Amount'].transform(lambda x: x.nlargest(2).iloc[-1])
df['NewAmt'] = np.select([m, m1], [s_1st, s_2nd], 0)

Out[1510]:
    Row_Num  Amount TransactionDate WeekStartDt   WeekEndDt       BusDt  NewAmt
0         1  349282      2020-02-17  2020-02-17  2020-02-21  2020-02-19       0
1         2   15440      2020-02-18  2020-02-17  2020-02-21  2020-02-19       0
2         3    6636      2020-02-19  2020-02-17  2020-02-21  2020-02-19  349282
3         4    6624      2020-02-20  2020-02-17  2020-02-21  2020-02-19   15440
4         5   -1526      2020-02-21  2020-02-17  2020-02-21  2020-02-19       0
5         1  502387      2020-02-24  2020-02-24  2020-02-28         NaT       0
6         2   27637      2020-02-25  2020-02-24  2020-02-28         NaT       0
7         3    9736      2020-02-26  2020-02-24  2020-02-28         NaT       0
8         4    6671      2020-02-27  2020-02-24  2020-02-28         NaT       0
9         5    5807      2020-02-28  2020-02-24  2020-02-28         NaT       0
10        1  238532      2020-03-02  2020-03-02  2020-03-06  2020-03-04       0
11        2   21399      2020-03-03  2020-03-02  2020-03-06  2020-03-04       0
12        3    5837      2020-03-04  2020-03-02  2020-03-06  2020-03-04  238532
13        4    5683      2020-03-05  2020-03-02  2020-03-06  2020-03-04   21399
14        5    5670      2020-03-06  2020-03-02  2020-03-06  2020-03-04       0
15        1  740786      2020-03-09  2020-03-09  2020-03-13         NaT       0
16        2   71530      2020-03-10  2020-03-09  2020-03-13         NaT       0
17        3    6713      2020-03-11  2020-03-09  2020-03-13         NaT       0
18        4    5648      2020-03-12  2020-03-09  2020-03-13         NaT       0
19        5    5571      2020-03-13  2020-03-09  2020-03-13         NaT       0

此解决方案可行,但输出中需要NaT。但是干得好!!您可以分离缺失和未缺失的观察值,使对未缺失的操作更容易,最后在一个数据帧中再次加入(追加),只需更改
df.groupby('BusDt')
by
df.groupby('WeekEndDt')
,并删除带有
df.dropna()
的行,该行也适用于NaT值。如果这对你有用,我将编辑原始答案。实际上,如果
BusDt
是星期五,这个解决方案就失效了。请注意,所有的
TransactionDate
值都是工作日,必须是
.groupby(['WeekStartDt','WeekEndDt'))
| Row_Num | Amount | Transaction Date | WeekStartDt | WeekEndDt  | BusDt      | NewAmt |
|---------|--------|------------------|-------------|------------|------------|--------|
| 1       | 349282 | 2020-02-17       | 2020-02-17  | 2020-02-21 | 2020-02-19 | 349282 |
| 2       | 15440  | 2020-02-18       | 2020-02-17  | 2020-02-21 | 2020-02-19 | 349282 |
| 3       | 6636   | 2020-02-19       | 2020-02-17  | 2020-02-21 | 2020-02-19 | 349282 |
| 4       | 6624   | 2020-02-20       | 2020-02-17  | 2020-02-21 | 2020-02-19 | 349282 |
| 5       | -1526  | 2020-02-21       | 2020-02-17  | 2020-02-21 | 2020-02-19 | 349282 |
| 1       | 502387 | 2020-02-24       | 2020-02-24  | 2020-02-28 | NaT        | 502387 |
| 2       | 27637  | 2020-02-25       | 2020-02-24  | 2020-02-28 | NaT        | 502387 |
| 3       | 9736   | 2020-02-26       | 2020-02-24  | 2020-02-28 | NaT        | 502387 |
| 4       | 6671   | 2020-02-27       | 2020-02-24  | 2020-02-28 | NaT        | 502387 |
| 5       | 5807   | 2020-02-28       | 2020-02-24  | 2020-02-28 | NaT        | 502387 |
| 1       | 238532 | 2020-03-02       | 2020-03-02  | 2020-03-06 | 2020-03-04 | 238532 |
| 2       | 21399  | 2020-03-03       | 2020-03-02  | 2020-03-06 | 2020-03-04 | 238532 |
| 3       | 5837   | 2020-03-04       | 2020-03-02  | 2020-03-06 | 2020-03-04 | 238532 |
| 4       | 5683   | 2020-03-05       | 2020-03-02  | 2020-03-06 | 2020-03-04 | 238532 |
| 5       | 5670   | 2020-03-06       | 2020-03-02  | 2020-03-06 | 2020-03-04 | 238532 |
| 1       | 740786 | 2020-03-09       | 2020-03-09  | 2020-03-13 | NaT        | 740786 |
| 2       | 71530  | 2020-03-10       | 2020-03-09  | 2020-03-13 | NaT        | 740786 |
| 3       | 6713   | 2020-03-11       | 2020-03-09  | 2020-03-13 | NaT        | 740786 |
| 4       | 5648   | 2020-03-12       | 2020-03-09  | 2020-03-13 | NaT        | 740786 |
| 5       | 5571   | 2020-03-13       | 2020-03-09  | 2020-03-13 | NaT        | 740786 |
records = [{'Row_Num': 1,
  'Amount': 349282,
  'Transaction_Date': ' 2020-02-17       ',
  'WeekStartDt': ' 2020-02-17  ',
  'WeekEndDt': ' 2020-02-21 ',
  'BusDt': ' 2020-02-19 '},
 {'Row_Num': 2,
  'Amount': 15440,
  'Transaction_Date': ' 2020-02-18       ',
  'WeekStartDt': ' 2020-02-17  ',
  'WeekEndDt': ' 2020-02-21 ',
  'BusDt': ' 2020-02-19 '},
 {'Row_Num': 3,
  'Amount': 6636,
  'Transaction_Date': ' 2020-02-19       ',
  'WeekStartDt': ' 2020-02-17  ',
  'WeekEndDt': ' 2020-02-21 ',
  'BusDt': ' 2020-02-19 '},
 {'Row_Num': 4,
  'Amount': 6624,
  'Transaction_Date': ' 2020-02-20       ',
  'WeekStartDt': ' 2020-02-17  ',
  'WeekEndDt': ' 2020-02-21 ',
  'BusDt': ' 2020-02-19 '},
 {'Row_Num': 5,
  'Amount': -1526,
  'Transaction_Date': ' 2020-02-21       ',
  'WeekStartDt': ' 2020-02-17  ',
  'WeekEndDt': ' 2020-02-21 ',
  'BusDt': ' 2020-02-19 '},
 {'Row_Num': 1,
  'Amount': 502387,
  'Transaction_Date': ' 2020-02-24       ',
  'WeekStartDt': ' 2020-02-24  ',
  'WeekEndDt': ' 2020-02-28 ',
  'BusDt': ' NaT        '},
 {'Row_Num': 2,
  'Amount': 27637,
  'Transaction_Date': ' 2020-02-25       ',
  'WeekStartDt': ' 2020-02-24  ',
  'WeekEndDt': ' 2020-02-28 ',
  'BusDt': ' NaT        '},
 {'Row_Num': 3,
  'Amount': 9736,
  'Transaction_Date': ' 2020-02-26       ',
  'WeekStartDt': ' 2020-02-24  ',
  'WeekEndDt': ' 2020-02-28 ',
  'BusDt': ' NaT        '},
 {'Row_Num': 4,
  'Amount': 6671,
  'Transaction_Date': ' 2020-02-27       ',
  'WeekStartDt': ' 2020-02-24  ',
  'WeekEndDt': ' 2020-02-28 ',
  'BusDt': ' NaT        '},
 {'Row_Num': 5,
  'Amount': 5807,
  'Transaction_Date': ' 2020-02-28       ',
  'WeekStartDt': ' 2020-02-24  ',
  'WeekEndDt': ' 2020-02-28 ',
  'BusDt': ' NaT        '},
 {'Row_Num': 1,
  'Amount': 238532,
  'Transaction_Date': ' 2020-03-02       ',
  'WeekStartDt': ' 2020-03-02  ',
  'WeekEndDt': ' 2020-03-06 ',
  'BusDt': ' 2020-03-04 '},
 {'Row_Num': 2,
  'Amount': 21399,
  'Transaction_Date': ' 2020-03-03       ',
  'WeekStartDt': ' 2020-03-02  ',
  'WeekEndDt': ' 2020-03-06 ',
  'BusDt': ' 2020-03-04 '},
 {'Row_Num': 3,
  'Amount': 5837,
  'Transaction_Date': ' 2020-03-04       ',
  'WeekStartDt': ' 2020-03-02  ',
  'WeekEndDt': ' 2020-03-06 ',
  'BusDt': ' 2020-03-04 '},
 {'Row_Num': 4,
  'Amount': 5683,
  'Transaction_Date': ' 2020-03-05       ',
  'WeekStartDt': ' 2020-03-02  ',
  'WeekEndDt': ' 2020-03-06 ',
  'BusDt': ' 2020-03-04 '},
 {'Row_Num': 5,
  'Amount': 5670,
  'Transaction_Date': ' 2020-03-06       ',
  'WeekStartDt': ' 2020-03-02  ',
  'WeekEndDt': ' 2020-03-06 ',
  'BusDt': ' 2020-03-04 '},
 {'Row_Num': 1,
  'Amount': 740786,
  'Transaction_Date': ' 2020-03-09       ',
  'WeekStartDt': ' 2020-03-09  ',
  'WeekEndDt': ' 2020-03-13 ',
  'BusDt': ' NaT        '},
 {'Row_Num': 2,
  'Amount': 71530,
  'Transaction_Date': ' 2020-03-10       ',
  'WeekStartDt': ' 2020-03-09  ',
  'WeekEndDt': ' 2020-03-13 ',
  'BusDt': ' NaT        '},
 {'Row_Num': 3,
  'Amount': 6713,
  'Transaction_Date': ' 2020-03-11       ',
  'WeekStartDt': ' 2020-03-09  ',
  'WeekEndDt': ' 2020-03-13 ',
  'BusDt': ' NaT        '},
 {'Row_Num': 4,
  'Amount': 5648,
  'Transaction_Date': ' 2020-03-12       ',
  'WeekStartDt': ' 2020-03-09  ',
  'WeekEndDt': ' 2020-03-13 ',
  'BusDt': ' NaT        '},
 {'Row_Num': 5,
  'Amount': 5571,
  'Transaction_Date': ' 2020-03-13       ',
  'WeekStartDt': ' 2020-03-09  ',
  'WeekEndDt': ' 2020-03-13 ',
  'BusDt': ' NaT        '}]

df = pd.DataFrame(records)
df[['Transaction_Date', 'WeekStartDt', 'WeekEndDt', 'BusDt']] = df[['Transaction_Date', 'WeekStartDt', 'WeekEndDt', 'BusDt']].apply(pd.to_datetime, errors='coerce')
df['NewAmt1'] = df['BusDt'].eq(df['Transaction_Date']) * df.groupby('WeekEndDt')['Amount'].transform(max)
df['NewAmt2'] = df['BusDt'].add(pd.Timedelta(days=1)).eq(df['Transaction_Date']) * df.groupby('WeekEndDt')['Amount'].transform(lambda x: x.nlargest(2).iloc[1])
df['NewAmt'] = df[['NewAmt1', 'NewAmt2']].sum(axis=1)
df
m = df.TransactionDate == df.BusDt
m1 = m.groupby([df.WeekStartDt, df.WeekEndDt]).shift(fill_value=False)
grps = df.groupby(['WeekStartDt', 'WeekEndDt'])
s_1st = grps['Amount'].transform('max')
s_2nd = grps['Amount'].transform(lambda x: x.nlargest(2).iloc[-1])
df['NewAmt'] = np.select([m, m1], [s_1st, s_2nd], 0)

Out[1510]:
    Row_Num  Amount TransactionDate WeekStartDt   WeekEndDt       BusDt  NewAmt
0         1  349282      2020-02-17  2020-02-17  2020-02-21  2020-02-19       0
1         2   15440      2020-02-18  2020-02-17  2020-02-21  2020-02-19       0
2         3    6636      2020-02-19  2020-02-17  2020-02-21  2020-02-19  349282
3         4    6624      2020-02-20  2020-02-17  2020-02-21  2020-02-19   15440
4         5   -1526      2020-02-21  2020-02-17  2020-02-21  2020-02-19       0
5         1  502387      2020-02-24  2020-02-24  2020-02-28         NaT       0
6         2   27637      2020-02-25  2020-02-24  2020-02-28         NaT       0
7         3    9736      2020-02-26  2020-02-24  2020-02-28         NaT       0
8         4    6671      2020-02-27  2020-02-24  2020-02-28         NaT       0
9         5    5807      2020-02-28  2020-02-24  2020-02-28         NaT       0
10        1  238532      2020-03-02  2020-03-02  2020-03-06  2020-03-04       0
11        2   21399      2020-03-03  2020-03-02  2020-03-06  2020-03-04       0
12        3    5837      2020-03-04  2020-03-02  2020-03-06  2020-03-04  238532
13        4    5683      2020-03-05  2020-03-02  2020-03-06  2020-03-04   21399
14        5    5670      2020-03-06  2020-03-02  2020-03-06  2020-03-04       0
15        1  740786      2020-03-09  2020-03-09  2020-03-13         NaT       0
16        2   71530      2020-03-10  2020-03-09  2020-03-13         NaT       0
17        3    6713      2020-03-11  2020-03-09  2020-03-13         NaT       0
18        4    5648      2020-03-12  2020-03-09  2020-03-13         NaT       0
19        5    5571      2020-03-13  2020-03-09  2020-03-13         NaT       0