如何跟踪"pandas"数据帧中的无序对



我有一个pd.Dataframe,列R_fighter-第一架战斗机的名称,B_fighter-第二架战斗机的名字,还有Winner列。数据按时间顺序排序,我想添加一列,如果战斗机之前见过面,并且R战斗机获胜,则将值设置为-1,如果B战斗机获胜-1,否则为0。如果保证战斗机可以按照相同的顺序再次相遇(R_fighter再次是R_fighterB_fighter再次是B_fighter(,那么可以执行以下操作:

last_winner_col = np.zeros(df_train.shape[0])
for x in df_train.groupby(['R_fighter', 'B_fighter'])['Winner']:
last_winner = 0
for idx, val in zip(x[1].index, x[1].values):
last_winner_col[idx] = last_winner
last_winner = 2 * val - 1

并将生成的pd.Series添加到数据集中。然而,他们的角色可能会在随后的战斗中发生变化。我想到的解决方案非常冗长和繁琐。如果有人提出一种方便的方法来追踪前一位获胜者,并考虑到战斗机顺序变化的可能性,我将不胜感激?

您可以创建一个;排序";版本,并使用它:

import pandas as pd
a = list("ABCDEFGH1234")
b = list("12341234ABCD")
win = list("ABCD12341234")
df = pd.DataFrame({"R_fighter":a, "B_fighter":b, "Winner":win})
# make a column with fixed order
df["combatants"] = df[['R_fighter', 'B_fighter']].apply(lambda x: sorted(x), axis=1)
# or simply set the result
df["w"] = df[['R_fighter', 'B_fighter', 'Winner']].apply(lambda x: '-1' 
if x[2]==x[0] 
else ('1' if x[2]==x[1] 
else '0'), axis=1 )
print(df)

输出:

R_fighter    B_fighter     Winner    combatants      w
0          A            1          A        [1, A]     -1
1          B            2          B        [2, B]     -1
2          C            3          C        [3, C]     -1
3          D            4          D        [4, D]     -1
4          E            1          1        [1, E]      1
5          F            2          2        [2, F]      1
6          G            3          3        [3, G]      1
7          H            4          4        [4, H]      1
8          1            A          1        [1, A]     -1
9          2            B          2        [2, B]     -1
10         3            C          3        [3, C]     -1
11         4            D          4        [4, D]     -1

要根据'combatants'(其中包含排序后的名称(获得获胜者,您可以执行以下操作:

df["w_combatants"] = df[['combatants', 'Winner']].apply(lambda x: '-1' 
if x[1]==x[0][0] 
else ('1' if x[1]==x[0][1] 
else '0'), axis=1 )

获取

R_fighter    B_fighter    Winner    combatants      w    w_combatants
0          A            1         A        [1, A]     -1               1
1          B            2         B        [2, B]     -1               1
2          C            3         C        [3, C]     -1               1
3          D            4         D        [4, D]     -1               1
4          E            1         1        [1, E]      1              -1
5          F            2         2        [2, F]      1              -1
6          G            3         3        [3, G]      1              -1
7          H            4         4        [4, H]      1              -1
8          1            A         1        [1, A]     -1              -1
9          2            B         2        [2, B]     -1              -1
10         3            C         3        [3, C]     -1              -1
11         4            D         4        [4, D]     -1              -1

基于@Patrick Artner的回答,我提出了以下解决方案:

df_train[['fighters']] = df_train[['R_fighter', 'B_fighter']].apply(lambda x :tuple(sorted(x)), axis = 1)
df_train[['fighter_ord_changed']] = df_train[['R_fighter', 'B_fighter']].apply(lambda x : np.argsort(x)[0], axis = 1)
last_winner_col = np.zeros(df_train.shape[0])
for x in df_train.groupby('fighters')['Winner']:
last_winner = 0
for idx, val in zip(x[1].index, x[1].values):
flag = df_train['fighter_ord_changed'][idx]
last_winner_col[idx] = -last_winner if flag else last_winner
last_winner = 2 * (val ^ flag) - 1

最新更新