model_event_counts.py
model_event_counts.py
#
TODO add quick explanation of this library
"""
Functions for adding event counts
"""
import pandas as pd
# from utils import *
#####################################
### Opponent previous move counts ###
#####################################
def get_opponent_move(sub_df):
"""
fills in the `opponent_move` column
"""
for i in range(len(sub_df)):
if i%2 == 0:
sub_df.at[i, 'opponent_move'] = sub_df.at[i + 1, 'player_move']
else:
sub_df.at[i, 'opponent_move'] = sub_df.at[i - 1, 'player_move']
return sub_df
def count_bot_prev_moves(sub_df):
"""
adds a tally for what the opponent played in prev round
"""
for i in range(2, len(sub_df)):
sub_df.at[i, 'opponent_rock_count'] = sub_df.at[i - 2, 'opponent_rock_count']
sub_df.at[i, 'opponent_paper_count'] = sub_df.at[i - 2, 'opponent_paper_count']
sub_df.at[i, 'opponent_scissors_count'] = sub_df.at[i - 2, 'opponent_scissors_count']
if sub_df.at[i - 2, 'opponent_move'] == "rock":
sub_df.at[i, 'opponent_rock_count'] += 1
elif sub_df.at[i - 2, 'opponent_move'] == "paper":
sub_df.at[i, 'opponent_paper_count'] += 1
elif sub_df.at[i - 2, 'opponent_move'] == "scissors":
sub_df.loc[i, 'opponent_scissors_count'] += 1
return sub_df
##################################
### Opponent transition counts ###
##################################
def get_player_prev_move(sub_df):
"""
get the previous moves
and add these moves as a new column to the orgininal dataframe
"""
for i in range(2, len(sub_df)):
if sub_df.iloc[i]['round_index']-1 == sub_df.iloc[i-2]['round_index']:
sub_df.at[i, 'previous_move'] = sub_df.at[i-2, 'player_move']
return sub_df
def get_opponent_prev_move(sub_df):
"""
get the opponent's previous moves
and add these moves as a new column to the orgininal dataframe
"""
for i in range(2, len(sub_df)):
if sub_df.iloc[i]['round_index']-1 == sub_df.iloc[i-2]['round_index']:
sub_df.at[i, 'opponent_previous_move'] = sub_df.at[i-2, 'opponent_move']
return sub_df
def count_bot_transitions(sub_df):
"""
tally for bot transitions from previous move to current move
"""
for i in range(3, len(sub_df), 2):
bot_pre = sub_df.get('previous_move').iloc[i]
bot_curr = sub_df.get('player_move').iloc[i]
if bot_pre and bot_pre != 'none' and not pd.isna(bot_pre) and \
bot_curr and bot_curr != 'none' and not pd.isna(bot_curr):
sub_df.at[i,'up_transition_count'] = sub_df.at[i-2, 'up_transition_count']
sub_df.at[i,'stay_transition_count'] = sub_df.at[i-2, 'stay_transition_count']
sub_df.at[i,'down_transition_count'] = sub_df.at[i-2, 'down_transition_count']
result = transition_lookup(bot_pre, bot_curr)
if result == 'up':
sub_df.at[i,'up_transition_count'] += 1
elif result == 'stay':
sub_df.at[i,'stay_transition_count'] += 1
elif result == 'down':
sub_df.at[i,'down_transition_count'] += 1
return sub_df
def count_bot_cournot_transitions(sub_df):
"""
tally for bot Cournot transitions from (human) opponent previous move to bot current move
"""
for i in range(3,len(sub_df),2):
human_pre=sub_df.get('opponent_previous_move').iloc[i]
bot_curr=sub_df.get('player_move').iloc[i]
if human_pre and human_pre != 'none' and not pd.isna(human_pre) and \
bot_curr and bot_curr != 'none' and not pd.isna(bot_curr):
sub_df.at[i,'cournot_up_transition_count'] = sub_df.at[i-2,'cournot_up_transition_count']
sub_df.at[i,'cournot_stay_transition_count'] = sub_df.at[i-2,'cournot_stay_transition_count']
sub_df.at[i,'cournot_down_transition_count'] = sub_df.at[i-2,'cournot_down_transition_count']
result = transition_lookup(human_pre, bot_curr)
if result=='up':
sub_df.at[i,'cournot_up_transition_count'] += 1
elif result=='stay':
sub_df.at[i,'cournot_stay_transition_count'] += 1
elif result=='down':
sub_df.at[i,'cournot_down_transition_count'] += 1
return sub_df
#################################
### Outcome transition counts ###
#################################
def get_opponent_prev_outcome(sub_df):
"""
get the opponent's previous outcomes
and add these outcomes as a new column to the orgininal dataframe
"""
for i in range(2, len(sub_df)):
if sub_df.iloc[i]['round_index']-1 == sub_df.iloc[i-2]['round_index']:
sub_df.at[i, 'previous_outcome'] = sub_df.at[i-2, 'player_outcome']
return sub_df
def count_bot_outcome_transitions(sub_df):
"""
tally based on previous_outcome (win, lose, tie) and bot's own transition (up, down, stay)
"""
for i in range(3, len(sub_df), 2):
bot_previous_outcome = sub_df.get('previous_outcome').iloc[i]
previous_move = sub_df.get('previous_move').iloc[i]
player_move = sub_df.get('player_move').iloc[i]
# get bot's transition_outcome from bot's previous move and current move
bot_transition = transition_lookup(previous_move, player_move)
if not pd.isna(bot_previous_outcome):
update_cols = [f'{outcome}_{trans}_count' for outcome in OUTCOMES for trans in TRANSITIONS]
for col in update_cols:
sub_df.at[i, col] = sub_df.at[i-2, col]
col_name = f'{bot_previous_outcome}_{bot_transition}_count'
sub_df.at[i, col_name] += 1
return sub_df
#################################################
### Outcome transition dual dependency counts ###
#################################################
def get_previous_current_transitions(sub_df):
"""
look for bot's previous/current transition for each round for outcome_trans_dual_depend_count function
"""
for i in range(5,len(sub_df),2):
previous_move = sub_df.get('previous_move').iloc[i]
cur_move = sub_df.get('player_move').iloc[i]
pre_pre_move=sub_df.get('previous_move').iloc[i-2]
# get bot's transition_outcome from bot's previous move and current move
cur_transition = transition_lookup(previous_move,cur_move)
previous_transition = transition_lookup(pre_pre_move,previous_move)
sub_df.at[i, 'previous_transition'] = previous_transition
sub_df.at[i, 'current_transition'] = cur_transition
return sub_df
def count_outcome_trans_dual_depend(sub_df):
for i in range(5, len(sub_df), 2):
bot_previous_outcome = sub_df.get('previous_outcome').iloc[i]
previous_transition = sub_df.get('previous_transition').iloc[i]
current_transition = sub_df.get('current_transition').iloc[i]
if not pd.isna(bot_previous_outcome):
update_cols = [f'{prev_trans}_{outcome}_{trans}_count' for prev_trans in TRANSITIONS for outcome in OUTCOMES for trans in TRANSITIONS]
for col in update_cols:
sub_df.at[i, col] = sub_df.at[i-2, col]
col_name = f'{previous_transition}_{bot_previous_outcome}_{current_transition}_count'
sub_df.at[i, col_name] += 1
return sub_df
# Convert event counts to "opponent_x_count" in all human rows
def change_to_human(sub_df, new_columns, original_columns):
"""
fill in column in every human row that track how many of each transitions its bot opponent made up to that point
new_columns: list of new column names
original_columns: list of original column names (in corresponding order with new column names)
NB: order of new_columns and original_columns must be matched
"""
for i in range(2, len(sub_df)):
if sub_df.iloc[i]['is_bot'] == 0 and sub_df.iloc[i]['round_index']-1 == sub_df.iloc[i-1]['round_index']:
for (new_c, old_c) in zip(new_columns, original_columns):
sub_df.at[i, new_c] = sub_df.at[i-1, old_c]
else:
continue
return sub_df
# Unify counts above
def get_event_counts(df, experiments):
"""
"""
for e in experiments:
# opponent previous move tallying
e = get_opponent_move(e)
e = count_bot_prev_moves(e)
# transition tallying
e = get_player_prev_move(e)
e = get_opponent_prev_move(e)
e = count_bot_transitions(e)
e = count_bot_cournot_transitions(e)
# outcome-based transition tallying
e = get_opponent_prev_outcome(e)
e = count_bot_outcome_transitions(e)
# dual transition-outcome tallying
e = get_previous_current_transitions(e)
e = count_outcome_trans_dual_depend(e)
# move bot tallies to human rows
e = change_to_human(
e,
new_columns=[
'opponent_previous_outcome', 'opponent_previous_transition', 'opponent_prev2_transition',
# transition counts
'opponent_up_transition_count', 'opponent_down_transition_count', 'opponent_stay_transition_count',
'opponent_cournot_up_transition_count', 'opponent_cournot_down_transition_count', 'opponent_cournot_stay_transition_count',
# outcome-transition counts
'opponent_win_up_count', 'opponent_win_down_count', 'opponent_win_stay_count',
'opponent_loss_up_count', 'opponent_loss_down_count', 'opponent_loss_stay_count',
'opponent_tie_up_count', 'opponent_tie_down_count', 'opponent_tie_stay_count',
# dual transition outcome counts
'opponent_up_win_up_count', 'opponent_up_win_down_count', 'opponent_up_win_stay_count',
'opponent_up_loss_up_count', 'opponent_up_loss_down_count', 'opponent_up_loss_stay_count',
'opponent_up_tie_up_count', 'opponent_up_tie_down_count', 'opponent_up_tie_stay_count',
'opponent_down_win_up_count', 'opponent_down_win_down_count', 'opponent_down_win_stay_count',
'opponent_down_loss_up_count', 'opponent_down_loss_down_count', 'opponent_down_loss_stay_count',
'opponent_down_tie_up_count', 'opponent_down_tie_down_count', 'opponent_down_tie_stay_count',
'opponent_stay_win_up_count', 'opponent_stay_win_down_count', 'opponent_stay_win_stay_count',
'opponent_stay_loss_up_count', 'opponent_stay_loss_down_count', 'opponent_stay_loss_stay_count',
'opponent_stay_tie_up_count', 'opponent_stay_tie_down_count', 'opponent_stay_tie_stay_count'
],
original_columns = [
'player_outcome', 'current_transition', 'previous_transition',
# transition counts
'up_transition_count', 'down_transition_count', 'stay_transition_count',
'cournot_up_transition_count', 'cournot_down_transition_count', 'cournot_stay_transition_count',
# outcome-transition counts
'win_up_count', 'win_down_count', 'win_stay_count',
'loss_up_count', 'loss_down_count', 'loss_stay_count',
'tie_up_count', 'tie_down_count', 'tie_stay_count',
# dual transition outcome counts
'up_win_up_count', 'up_win_down_count', 'up_win_stay_count',
'up_loss_up_count', 'up_loss_down_count', 'up_loss_stay_count',
'up_tie_up_count', 'up_tie_down_count', 'up_tie_stay_count',
'down_win_up_count', 'down_win_down_count', 'down_win_stay_count',
'down_loss_up_count', 'down_loss_down_count', 'down_loss_stay_count',
'down_tie_up_count', 'down_tie_down_count', 'down_tie_stay_count',
'stay_win_up_count', 'stay_win_down_count', 'stay_win_stay_count',
'stay_loss_up_count', 'stay_loss_down_count', 'stay_loss_stay_count',
'stay_tie_up_count', 'stay_tie_down_count', 'stay_tie_stay_count'
]
)
return experiments