Python 如何跟踪“pandas”数据帧中的无序对
我有一个Python 如何跟踪“pandas”数据帧中的无序对,python,pandas,pandas-groupby,Python,Pandas,Pandas Groupby,我有一个pd.Dataframe,列为R\u战斗机——第一架战斗机的名称,B\u战斗机——第二架战斗机的名称和获胜者列。数据是按时间顺序排序的,我想添加一列,其中如果战斗机以前见过面,并且R战斗机获胜,则将值设置为-1,如果B战斗机获胜-1,否则设置为0。如果保证战斗机可以按照相同的顺序再次会合(R\U战斗机再次是R\U战斗机,B\U战斗机再次是B\U战斗机),则可以执行以下操作: last_winner_col = np.zeros(df_train.shape[0]) for x in d
pd.Dataframe
,列为R\u战斗机
——第一架战斗机的名称,B\u战斗机
——第二架战斗机的名称和获胜者
列。数据是按时间顺序排序的,我想添加一列,其中如果战斗机以前见过面,并且R
战斗机获胜,则将值设置为-1
,如果B
战斗机获胜-1
,否则设置为0
。如果保证战斗机可以按照相同的顺序再次会合(R\U战斗机
再次是R\U战斗机
,B\U战斗机
再次是B\U战斗机
),则可以执行以下操作:
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
要根据“战斗人员”
(其中包含已排序的姓名)获得获胜者,您可以执行以下操作:
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 answer,我提出了以下解决方案:
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