Reputation: 103
I have a data frame of :
dfAll = match ID Team A Hero 1.1 Team A Hero 1.2 Team A Hero 1.3
123124140 (1, 2) (2, 3) (1, 3)
123123124 (4, 1) (3, 4) (1, 5)
and so on..
and I have a crosstable:
dfEloCross = 1 2 3 4 5
1 NaN -1.0 +2.0 -8.0 +5.0
2 +1.0 NaN +2.5 +3.0 0
3 -2.0 -2.5 NaN +5.5 -3.5
4 +8.0 -3.0 -5.5 NaN +2.8
5 -5.0 0 +3.5 -2.8 NaN
And I wanted for each matchup to return a value as so, where it is vertical against horizontal.
df1 = matchups 1 matchups 2 matchups 3
+1.0 -2.5 -2.0
-8.0 -5.5 -5.0
I've tried using this code:
for uv in range(1, 6):
for xv in range(1,6):
dfAll['Matchup' + ' ' + str(uv) + '.' + str(xv)] = dfAll['Team A Hero' + ' ' + str(uv) + '.' + str(xv)].apply(lambda x: dfEloCross.lookup([x[0]],[x[1]])[0])
And it works fine for the first column of Team A Hero 1.1
But
returns key error for others
KeyError: 'One or more column labels was not found
I'm a beginner so I would love to get all the help I can get. Thanks in Advance!
EDIT
For reference, here's a snippet of my dataframe:
dfAll = {'Team A Hero 1.1': {0: '(22, 21)', 1: '(12, 3)', 2: '(6, 7)', 3: '(13, 18)', 4: '(28, 7)', 5: '(9, 36)', 6: '(36, 7)', 7: '(9, 7)', 8: '(4, 61)'}, 'Team A Hero 1.2': {0: '(22, 43)', 1: '(12, 15)', 2: '(6, 31)', 3: '(13, 49)', 4: '(28, 13)', 5: '(9, 58)', 6: '(36, 13)', 7: '(9, 8)', 8: '(4, 64)'}, 'Team A Hero 1.3': {0: '(22, 71)', 1: '(12, 30)', 2: '(6, 40)', 3: '(13, 64)', 4: '(28, 56)', 5: '(9, 78)', 6: '(36, 30)', 7: '(9, 13)', 8: '(4, 72)'}, 'Team A Hero 1.4': {0: '(22, 77)', 1: '(12, 65)', 2: '(6, 43)', 3: '(13, 65)', 4: '(28, 87)', 5: '(9, 95)', 6: '(36, 80)', 7: '(9, 15)', 8: '(4, 76)'}, 'Team A Hero 1.5': {0: '(22, 85)', 1: '(12, 103)', 2: '(6, 69)', 3: '(13, 107)', 4: '(28, 106)', 5: '(9, 107)', 6: '(36, 98)', 7: '(9, 112)', 8: '(4, 84)'}, 'Team A Hero 2.1': {0: '(28, 21)', 1: '(58, 3)', 2: '(20, 7)', 3: '(54, 18)', 4: '(44, 7)', 5: '(28, 36)', 6: '(49, 7)', 7: '(52, 7)', 8: '(51, 61)'}}
Upvotes: 2
Views: 268
Reputation: 164653
You do not need to use nested loops. Instead, you can use the pd.DataFrame.lookup
method available to Pandas.
In this case, you can iterate your Team columns, unpack your coordinates and perform your lookup one series at a time:
from ast import literal_eval
df1 = pd.DataFrame({'matchID': [123124140, 123123124],
'TeamA_1.1': ['(1, 2)', '(4, 1)'],
'TeamA_1.2': ['(2, 3)', '(3, 4)']})
# convert mapping table columns to integer type
dfEloCross.columns = dfEloCross.columns.astype(int)
# calculate columns which need mapping
team_cols = df1.columns[df1.columns.str.startswith('Team')]
# cycle each column, strip column & row coordinates and use with lookup
for col in team_cols:
c, r = zip(*df1[col].apply(literal_eval))
df1[col] = dfEloCross.lookup(r, c)
print(df1)
TeamA_1.1 TeamA_1.2 matchID
0 1.0 -2.5 123124140
1 -8.0 -5.5 123123124
Upvotes: 2