So I have a Pandas dataframe, df, which looks like this (with other columns):
| timestamp | player | event | location_x | location_y | location_z | dist |
|---|---|---|---|---|---|---|
| 2021-07-14 22:54:28.001000 | Bob | 'PlayerMoveEvent' | 10 | 10 | 10 | ? |
| 2021-07-14 22:54:28.001600 | Alice | 'PlayerJoinEvent' | NaN | NaN | NaN | ? |
| 2021-07-14 22:54:28.001600 | Alice | 'PlayerMoveEvent' | 20 | 20 | 20 | ? |
| 2021-07-14 22:54:28.001670 | Bob | 'PlayerMoveEvent' | 11 | 10 | 10 | ? |
| 2021-07-14 22:54:28.001740 | Eve | 'PlayerMoveEvent' | 5 | 15 | 9 | ? |
| 2021-07-14 22:54:28.001670 | Eve | 'PlayerQuitEvent' | NaN | NaN | NaN | ? |
| 2021-07-14 22:54:28.001820 | Alice | 'PlayerMoveEvent' | 18 | 20 | 19 | ? |
Every time a player moves, an event is triggered and their position is logged.
Now I want to figure out the distance √((x2-x1)^2 + (y2-y1)^2 + (z2-z1)^2) between two given players, in this case Alice and Bob, and add it to the end of the dataframe as a new column.
For a row with another player, or a non-'PlayerMoveEvent', it would just repeat the same value from the previous row, because it'd be using the older locations (I tried doing this by storing the locations as separate lists, shown below).
def player_distance(df, player_0, player_1):
player_0_location = [None, None, None]
player_1_location = [None, None, None]
I've tried many things (before I was using .apply with a lambda function "dist"), but now I'm trying to do it all in one function. I know that iterrows() isn't doing what I think it does below, because none of the below worked as an IF statement, even if they worked when tested manually outside of the function:
if((df.loc[i]['player'][0]) == player_0) & (df.loc[i]['event'][0]) == 'PlayerMoveEvent')):
if((df.loc[i]['player'].item()) == player_0) & (df.loc[i]['event'].item()) == 'PlayerMoveEvent')):
both of these neither work when type-casted to string
if((df.loc[i]['player'].item() == player_0) & (df.loc[i]['event'].item() == 'PlayerMoveEvent')):
if((j['player'] == player_0) and (j['event'] == 'PlayerMoveEvent')):
if((j['player'].eq(player_0)) & (j['event'].eq('PlayerMoveEvent'))):
def player_distance(df, player_0, player_1):
player_0_location = [None, None, None]
player_1_location = [None, None, None]
for i, j in df.iterrows():
# PROBLEM LINE
if((df.loc[i]['player'][0]) == player_0) & (df.loc[i]['event'][0]) == 'PlayerMoveEvent')):
# this line always gives a "ValueError: The truth value of a Series is ambiguous. Use a.empty, a.bool(), a.item(), a.any() or a.all()." error
player_0_location[0] = df.loc[i, 'location_x'].values[0]
player_0_location[1] = df.loc[i, 'location_y'].values[0]
player_0_location[2] = df.loc[i, 'location_z'].values[0]
# PROBLEM LINE
if((df.loc[i]['player'][0]) == player_1) & (df.loc[i]['event'][0]) == 'PlayerMoveEvent')):
player_1_location[0] = df.loc[i, 'location_x'].values[0]
player_1_location[1] = df.loc[i, 'location_y'].values[0]
player_1_location[2] = df.loc[i, 'location_z'].values[0]
if ((None not in player_0_location) and (None not in player_1_location)):
df.loc[i]['dist'] = (((player_0_location[0] - player_1_location[0]) ** 2) + ((player_0_location[1] - player_1_location[1]) ** 2) + ((player_0_location[2] - player_1_location[2]) ** 2)) ** 0.5