Created
April 9, 2016 17:29
-
-
Save kudkudak/63a8d5530cf324a85bd61eb8bb39bfec to your computer and use it in GitHub Desktop.
Script used to calculate final ranking
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import pandas as pd | |
import json | |
import copy | |
def krakrobot2016_calculate_ranking(data): | |
data = copy.deepcopy(data) | |
def get_wins(player_a, player_b): | |
only_ab = A_pairs[(A_pairs["id_x"] == player_a) & (A_pairs["id_y"] == player_b)] | |
wins = only_ab[(only_ab['points_x'] > only_ab['points_y']) | \ | |
((only_ab['points_x'] == only_ab['points_y']) & (only_ab['time_x'] < only_ab['time_y']))] | |
return wins | |
def order_by_points_then_wins(player_a, player_b): | |
points_a = A[A['id'] == player_a]['points'].sum() | |
points_b = A[A['id'] == player_b]['points'].sum() | |
wins_a = len(get_wins(player_a, player_b)) | |
wins_b = len(get_wins(player_b, player_a)) | |
if points_a > points_b: | |
return 1 | |
elif points_a < points_b: | |
return -1 | |
else: | |
if wins_a > wins_b: | |
return 1 | |
elif wins_a < wins_b: | |
return -1 | |
else: | |
return 0 | |
# 1. Enrich with map_id | |
for map_id, map_results in enumerate(data): | |
for team_result in map_results: | |
team_result['map_id'] = map_id | |
# 2. Construct records | |
n_maps, n_teams = len(data), len(data[0]) | |
team_ids = [team['id'] for team in data[0]] | |
A = pd.concat([pd.DataFrame(map_results, index=range(map_id * n_teams, (map_id + 1) * n_teams)) \ | |
for map_id, map_results in enumerate(data)]) | |
A_pairs = pd.merge(A, A, on="map_id") # SQL join on map_id, so every row is constructed from 2 rows having same id | |
assert len(A) == n_maps * n_teams, "Number of observations is number of maps x number of teams" | |
assert len(A_pairs) == (n_teams ** 2) * n_maps # Each map is bloated into all pairs | |
# 3. Order range(n_teams) using first points then wins | |
points = A.groupby("id").sum() | |
points = points.sort("points", ascending=False)['points'] | |
point_win_order = sorted(points.index.tolist(), cmp=order_by_points_then_wins) | |
point_order = sorted(points.index.tolist(), key=lambda x: points[x]) | |
for id_a in team_ids: | |
for id_b in team_ids: | |
assert (point_win_order.index(id_a) > point_win_order.index(id_b)) \ | |
== (point_order.index(id_a) > point_order.index(id_b)) or points[id_a] == points[id_b], \ | |
"Points order should have priority" | |
return points[point_win_order] | |
if __name__ == "__main__": | |
data = json.loads(open("final_test_result.json", "r").read()) | |
points = krakrobot2016_calculate_ranking(data) | |
print zip(points.index, points.values) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment