import matplotlib
import seaborn as sns
import pandas as pd
import requests
import os
import numpy as np
cache files locally as they will never change again
url2021 = 'https://s3.amazonaws.com/donkanator.com/stats/endseason/stats_na_6_2021.gz'
url2020 = 'https://s3.amazonaws.com/donkanator.com/stats/endseason/stats_na_6_2020.gz'
if not os.path.exists('stats_na_6_2021.gz'):
with open('stats_na_6_2021.gz', 'wb') as out_file:
content = requests.get(url2021, stream=True).content
out_file.write(content)
print("downloaded 2021 file")
else:
print("2021 file exists")
file_size = os.path.getsize('stats_na_6_2021.gz')
print("File Size is :", round(file_size/1024/1024,1), "MB")
if not os.path.exists('stats_na_6_2020.gz'):
with open('stats_na_6_2020.gz', 'wb') as out_file:
content = requests.get(url2020, stream=True).content
out_file.write(content)
print("downloaded 2020 file")
else:
print("2020 file exists")
file_size = os.path.getsize('stats_na_6_2020.gz')
print("File Size is :", round(file_size/1024/1024,1), "MB")
2021 file exists File Size is : 1.4 MB 2020 file exists File Size is : 0.8 MB
# Basics
stats2020 = pd.read_parquet("stats_na_6_2020.gz")
print("Stats2020 :", len(stats2020), " lines")
stats2021 = pd.read_parquet("stats_na_6_2021.gz")
print("Stats2021 :", len(stats2021), " lines")
Stats2020 : 39085 lines Stats2021 : 65498 lines
#Bring the files together and see differences
stats= pd.concat([stats2020,stats2021], axis=0, ignore_index=True)
print("For you information: Different columns across datasets:")
set(stats2021.columns).symmetric_difference(set(stats2020.columns))
For you information: Different columns across datasets:
{'Accuracy', 'Headshots', 'Revives'}
#Total number of kills per year
stats['year'] = pd.DatetimeIndex(stats['match_date']).year
stats['quarter'] = pd.DatetimeIndex(stats['match_date']).quarter #this is for later
stats['month'] = pd.DatetimeIndex(stats['match_date']).month #this is for later
stats[["year","Kills"]].groupby("year").sum()
Kills | |
---|---|
year | |
2020 | 250477 |
2021 | 451438 |
#Set pandas format
pd.set_option('display.max_rows', 100)
pd.set_option("display.max_columns", 15)
pd.set_option("display.max_colwidth", 20)
pd.set_option("display.width", 400)
pd.options.display.float_format = '{:.2f}'.format
stats.info()
<class 'pandas.core.frame.DataFrame'> RangeIndex: 104583 entries, 0 to 104582 Data columns (total 56 columns): # Column Non-Null Count Dtype --- ------ -------------- ----- 0 AdjScore 104583 non-null int32 1 Airstrike 104583 non-null int32 2 All_Deaths 104583 non-null int32 3 Artillery 104583 non-null int32 4 Colt 104583 non-null int32 5 Deaths 104583 non-null int32 6 Dynamite 104583 non-null int32 7 Flame 104583 non-null int32 8 Grenade 104583 non-null int32 9 Killer 104583 non-null object 10 Kills 104583 non-null int32 11 Knife 104583 non-null int32 12 Luger 104583 non-null int32 13 MG42 104583 non-null int32 14 MP40 104583 non-null int32 15 OSP_Damage_Given 104583 non-null int32 16 OSP_Damage_Received 104583 non-null int32 17 OSP_Deaths 104583 non-null int32 18 OSP_Eff 104583 non-null int32 19 OSP_Gibs 104583 non-null int32 20 OSP_Kills 104583 non-null int32 21 OSP_Player 104583 non-null object 22 OSP_Score 104583 non-null int32 23 OSP_Suicides 104583 non-null int32 24 OSP_TK 104583 non-null int32 25 OSP_Team 104583 non-null object 26 OSP_Team_Damage 104583 non-null int32 27 Panzerfaust 104583 non-null int32 28 Sniper 104583 non-null int32 29 Sten 104583 non-null int32 30 Suicides 104583 non-null int32 31 TK 104583 non-null int32 32 TKd 104583 non-null int32 33 Thompson 104583 non-null int32 34 Venom 104583 non-null int32 35 class 104583 non-null object 36 game_result 104583 non-null object 37 map 104583 non-null object 38 match_date 104583 non-null object 39 osp_guid 104583 non-null object 40 pb_guid 104583 non-null object 41 player_strip 104583 non-null object 42 round_diff 104583 non-null int32 43 round_guid 104583 non-null object 44 round_num 104583 non-null int32 45 round_order 104583 non-null int32 46 round_time 104583 non-null int32 47 round_win 104583 non-null int32 48 side 104583 non-null object 49 team_name 104583 non-null object 50 Accuracy 65498 non-null float64 51 Headshots 65498 non-null float64 52 Revives 65498 non-null float64 53 year 104583 non-null int64 54 quarter 104583 non-null int64 55 month 104583 non-null int64 dtypes: float64(3), int32(37), int64(3), object(13) memory usage: 29.9+ MB
stats.iloc[:,30:45].describe()
Suicides | TK | TKd | Thompson | Venom | round_diff | round_num | |
---|---|---|---|---|---|---|---|
count | 104583.00 | 104583.00 | 104583.00 | 104583.00 | 104583.00 | 104583.00 | 104583.00 |
mean | 1.73 | 0.39 | 0.39 | 1.63 | 0.01 | 156.59 | 1.50 |
std | 2.00 | 0.71 | 0.67 | 2.97 | 0.20 | 183.74 | 0.50 |
min | 0.00 | 0.00 | 0.00 | 0.00 | 0.00 | -180.00 | 1.00 |
25% | 0.00 | 0.00 | 0.00 | 0.00 | 0.00 | 0.00 | 1.00 |
50% | 1.00 | 0.00 | 0.00 | 0.00 | 0.00 | 87.00 | 1.00 |
75% | 2.00 | 1.00 | 1.00 | 2.00 | 0.00 | 300.00 | 2.00 |
max | 46.00 | 12.00 | 8.00 | 30.00 | 21.00 | 811.00 | 2.00 |
stats.describe(include=['O'])
Killer | OSP_Player | OSP_Team | class | game_result | map | match_date | osp_guid | pb_guid | player_strip | round_guid | side | team_name | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|
count | 104583 | 104583 | 104583 | 104583 | 104583 | 104583 | 104583 | 104583 | 104583 | 104583 | 104583 | 104583 | 104583 |
unique | 503 | 1903 | 3 | 6 | 5 | 28 | 8474 | 2651 | 79 | 1 | 8617 | 3 | 1 |
top | john_mullins | cakel | Axis | R1MSB | Ice | 2020-04-02 23:28:15 | notused | 9b16cb2ef5e01515... | Defense | notused | |||
freq | 4134 | 3553 | 51615 | 73958 | 52504 | 19970 | 174 | 70711 | 99923 | 104583 | 26 | 51614 | 104583 |
stats.shape
(104583, 56)
stats.head(10)
AdjScore | Airstrike | All_Deaths | Artillery | Colt | Deaths | Dynamite | ... | team_name | Accuracy | Headshots | Revives | year | quarter | month | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0 | 10 | 1 | 10 | 2 | 0 | 7 | 0 | ... | notused | NaN | NaN | NaN | 2020 | 2 | 4 |
1 | 9 | 0 | 8 | 0 | 0 | 3 | 0 | ... | notused | NaN | NaN | NaN | 2020 | 2 | 4 |
2 | 42 | 0 | 6 | 0 | 0 | 5 | 0 | ... | notused | NaN | NaN | NaN | 2020 | 2 | 4 |
3 | 18 | 1 | 12 | 0 | 0 | 9 | 0 | ... | notused | NaN | NaN | NaN | 2020 | 2 | 4 |
4 | 20 | 0 | 6 | 0 | 0 | 3 | 0 | ... | notused | NaN | NaN | NaN | 2020 | 2 | 4 |
5 | 2 | 0 | 9 | 0 | 0 | 8 | 0 | ... | notused | NaN | NaN | NaN | 2020 | 2 | 4 |
6 | 6 | 2 | 7 | 0 | 0 | 5 | 0 | ... | notused | NaN | NaN | NaN | 2020 | 2 | 4 |
7 | 24 | 0 | 5 | 0 | 0 | 4 | 0 | ... | notused | NaN | NaN | NaN | 2020 | 2 | 4 |
8 | 8 | 0 | 7 | 0 | 0 | 4 | 0 | ... | notused | NaN | NaN | NaN | 2020 | 2 | 4 |
9 | 13 | 0 | 10 | 0 | 0 | 6 | 0 | ... | notused | NaN | NaN | NaN | 2020 | 2 | 4 |
10 rows × 56 columns
stats[["round_guid", "map", "match_date" , "Killer", "OSP_Team","Kills", "OSP_Damage_Given", "game_result", "round_num", "round_win"]].head(20)
round_guid | map | match_date | Killer | OSP_Team | Kills | OSP_Damage_Given | game_result | round_num | round_win | |
---|---|---|---|---|---|---|---|---|---|---|
0 | 00a51f47c49706a2... | Ice | 2020-04-08 18:54:37 | murkey | Axis | 9 | 2202 | R1MSB | 1 | 1 |
1 | 00a51f47c49706a2... | Ice | 2020-04-08 18:54:37 | cliffdark | Axis | 3 | 406 | R1MSB | 1 | 1 |
2 | 00a51f47c49706a2... | Ice | 2020-04-08 18:54:37 | chinamann | Axis | 8 | 1350 | R1MSB | 1 | 1 |
3 | 00a51f47c49706a2... | Ice | 2020-04-08 18:54:37 | jimmy | Allies | 7 | 1308 | R1MSB | 1 | 0 |
4 | 00a51f47c49706a2... | Ice | 2020-04-08 18:54:37 | mean | Allies | 7 | 1361 | R1MSB | 1 | 0 |
5 | 00a51f47c49706a2... | Ice | 2020-04-08 18:54:37 | miles | Allies | 1 | 818 | R1MSB | 1 | 0 |
6 | 800f707fc5f4f006... | Ice | 2020-04-08 19:00:58 | murkey | Allies | 11 | 4983 | WON | 2 | 1 |
7 | 800f707fc5f4f006... | Ice | 2020-04-08 19:00:58 | cliffdark | Allies | 5 | 1559 | WON | 2 | 1 |
8 | 800f707fc5f4f006... | Ice | 2020-04-08 19:00:58 | chinamann | Allies | 7 | 2636 | WON | 2 | 1 |
9 | 800f707fc5f4f006... | Ice | 2020-04-08 19:00:58 | jimmy | Axis | 2 | 2388 | LOST | 2 | 0 |
10 | 800f707fc5f4f006... | Ice | 2020-04-08 19:00:58 | mean | Axis | 8 | 2930 | LOST | 2 | 0 |
11 | 800f707fc5f4f006... | Ice | 2020-04-08 19:00:58 | miles | Axis | 3 | 1433 | LOST | 2 | 0 |
12 | ad23b7d74145c9e5... | Ice | 2020-04-08 19:06:39 | murkey | Allies | 7 | 874 | R1MSB | 1 | 0 |
13 | ad23b7d74145c9e5... | Ice | 2020-04-08 19:06:39 | cliffdark | Allies | 2 | 607 | R1MSB | 1 | 0 |
14 | ad23b7d74145c9e5... | Ice | 2020-04-08 19:06:39 | chinamann | Allies | 6 | 1491 | R1MSB | 1 | 0 |
15 | ad23b7d74145c9e5... | Ice | 2020-04-08 19:06:39 | jimmy | Axis | 4 | 898 | R1MSB | 1 | 1 |
16 | ad23b7d74145c9e5... | Ice | 2020-04-08 19:06:39 | mean | Axis | 5 | 1036 | R1MSB | 1 | 1 |
17 | ad23b7d74145c9e5... | Ice | 2020-04-08 19:06:39 | miles | Axis | 2 | 508 | R1MSB | 1 | 1 |
18 | c805865abb22ac97... | Ice | 2020-04-08 19:10:08 | murkey | Axis | 4 | 1440 | WON | 2 | 1 |
19 | c805865abb22ac97... | Ice | 2020-04-08 19:10:08 | cliffdark | Axis | 4 | 1502 | WON | 2 | 1 |
Some cleaning steps I have discovered mostly after the fact
print("Lines before general cleansing: ", len(stats))
stats_original = stats.copy()
#Remove some aliases
stats = stats[~stats["Killer"].isin(["WolfPlayer9999", "blackmagik0inc.", "blackmagik7inc."])]
#Remove unknown maps
stats = stats[~stats["map"].isin(['Not listed', 'No info'])]
#Remove disconnected players that have no OSP stats and team affiliation
stats = stats[~stats["OSP_Team"].isin(['0'])]
print("Lines after general cleansing: ", len(stats))
Lines before general cleansing: 104583 Lines after general cleansing: 102828
#Remove games with less than 5v5 players
player_nums = stats["round_guid"].value_counts()
games_under5_players = player_nums[player_nums < 9].index.values
print("Lines before removing smaller matches: ", len(stats))
stats = stats[~stats['round_guid'].isin(games_under5_players)]
print("Lines after removing smaller matches: ", len(stats))
Lines before removing smaller matches: 102828 Lines after removing smaller matches: 99580
#Remove some duplicate players probably caused by rename process
stats.drop_duplicates(["Killer", "round_guid"],inplace=True)
# player_dups = stats.groupby(["Killer", "round_guid"]).count()["round_num"].reset_index()
# player_dups[player_dups["round_num"]>1].head(100)
Set the stage - who are the players and what are the maps?
#We will work with round2 (final) stats
tmp_heat = stats[stats["round_num"] == 2]
#players
tmp_games = tmp_heat[["Killer", "round_guid"]].groupby(["Killer"]).agg({'round_guid' : "count"})
tmp_games.sort_values(by="round_guid", ascending=False).head(30)
#limit players to at least 120 games
tmp_games_filt = tmp_games[tmp_games["round_guid"]>120].sort_values(by="round_guid")
#Maps
tmp_maps = tmp_heat[["map", "round_guid"]].groupby(["map"]).agg({'round_guid' : pd.Series.nunique})
tmp_maps.sort_values(by="round_guid", ascending=False).head(20)
round_guid | |
---|---|
map | |
Ice | 760 |
Frostbite | 647 |
Village | 501 |
Adlernest | 446 |
Beach | 386 |
Base | 322 |
Cipher | 226 |
Escape | 184 |
Password | 181 |
Assault | 147 |
Sub | 113 |
UFO | 41 |
Tunordic | 29 |
Tundra | 17 |
Chateau | 16 |
Brewdog | 11 |
Delivery | 10 |
Radar | 6 |
Keep | 6 |
Tram | 4 |
tmp_wins = stats[stats["round_num"] == 2]
tmp_wins = tmp_wins[tmp_wins["Killer"].isin(tmp_games_filt.index.values)]
tmp_wins = tmp_wins.groupby(["Killer","game_result"]).count()["Kills"].reset_index()
tmp_wins.columns = ["Killer","game_result","Count"]
tmp_wins = tmp_wins.pivot(index="Killer",columns="game_result", values="Count")
tmp_wins["Total"] = tmp_wins.sum(axis=1)
tmp_wins["Win%"] = tmp_wins["WON"]/tmp_wins["Total"]
tmp_wins["Draw%"] = tmp_wins["FULLHOLD"]/tmp_wins["Total"]
tmp_wins["Loss%"] = tmp_wins["LOST"]/tmp_wins["Total"]
pd.options.display.float_format = '{:.1%}'.format
tmp_wins[["Win%","Draw%","Loss%"]].sort_values(by="Win%", ascending=False).head(50)
game_result | Win% | Draw% | Loss% |
---|---|---|---|
Killer | |||
diego | 54.9% | 4.5% | 40.6% |
kazz | 53.5% | 8.0% | 38.5% |
brandon | 52.7% | 5.6% | 41.8% |
pingrage | 52.4% | 9.7% | 37.8% |
ding | 51.8% | 5.9% | 42.2% |
murkey | 51.7% | 7.3% | 41.0% |
druwin | 50.9% | 6.9% | 42.2% |
vein | 50.9% | 4.7% | 44.4% |
xill | 50.9% | 6.1% | 43.1% |
ipod | 50.4% | 4.7% | 44.9% |
pimp | 50.0% | 8.0% | 42.0% |
yeniceri | 50.0% | 4.4% | 45.6% |
kittens | 50.0% | 7.1% | 42.9% |
john_mullins | 49.9% | 7.4% | 42.7% |
fro | 49.9% | 7.1% | 43.1% |
raiser | 49.0% | 7.3% | 43.6% |
miles | 48.8% | 6.3% | 44.9% |
mmbird | 48.8% | 7.2% | 44.0% |
jaytee | 48.7% | 8.3% | 43.0% |
bru | 48.6% | 7.4% | 44.0% |
donka | 48.4% | 6.8% | 44.8% |
illkilla | 48.3% | 5.1% | 46.6% |
tragic | 48.2% | 8.9% | 42.9% |
reker | 48.0% | 6.4% | 45.6% |
yyz | 47.8% | 6.8% | 45.3% |
souldriver | 47.7% | 6.1% | 46.2% |
source | 47.6% | 6.5% | 45.9% |
flogzero | 47.5% | 7.9% | 44.6% |
donkey | 47.4% | 6.7% | 45.9% |
detdet | 47.2% | 3.6% | 49.2% |
conscious | 47.1% | 7.0% | 45.9% |
warrior | 47.1% | 7.3% | 45.6% |
rob | 46.8% | 7.5% | 45.7% |
shaz | 46.7% | 5.2% | 48.1% |
doza | 46.6% | 5.9% | 47.5% |
nigel | 46.4% | 7.1% | 46.5% |
cliffdark | 46.3% | 6.6% | 47.1% |
parcher | 46.2% | 7.0% | 46.7% |
dillweed | 45.9% | 7.3% | 46.8% |
fonze | 45.7% | 7.6% | 46.7% |
joep | 45.7% | 5.1% | 49.1% |
blackmagik | 45.6% | 7.0% | 47.4% |
cakel | 45.6% | 7.2% | 47.2% |
firehot | 45.5% | 6.8% | 47.7% |
sem | 45.3% | 3.4% | 51.4% |
jam | 45.0% | 10.0% | 45.0% |
luna | 45.0% | 8.5% | 46.5% |
mooshu | 45.0% | 7.0% | 48.0% |
eternal | 44.9% | 5.8% | 49.3% |
jimmy | 44.7% | 4.8% | 50.5% |
Here we probably need to state that the games are handpicked/adjusted for fairness and those with higher percentages are probably performing better than expected, people down the middle are just right, and the bottom is not shown.
#Get heatmap of player vs map by win percentage
#limit maps to at least 40 games played
tmp_maps_filt = tmp_maps[tmp_maps["round_guid"]>40].sort_values(by="round_guid")
#This is a lazy count of round2 holds. Winning* includes fullholds here
tmp_heat = tmp_heat[["Killer","map", "round_win", "round_guid"]].groupby(["Killer","map"]).agg({'round_win' : "sum", 'round_guid' : "count"}).reset_index()
tmp_heat = tmp_heat[tmp_heat["Killer"].isin(tmp_games_filt.index.values)]
tmp_heat = tmp_heat[tmp_heat["map"].isin(tmp_maps_filt.index.values)]
tmp_heat = tmp_heat[tmp_heat["round_guid"]>4]
tmp_heat["win%"] = tmp_heat["round_win"]/tmp_heat["round_guid"]
tmp_heat.sort_values(by="win%").head(50)
Killer | map | round_win | round_guid | win% | |
---|---|---|---|---|---|
1156 | jam | Cipher | 0 | 14 | 0.0% |
2031 | rob | UFO | 0 | 5 | 0.0% |
488 | conscious | Escape | 0 | 5 | 0.0% |
1207 | jimmy | Password | 0 | 8 | 0.0% |
539 | cypher | Assault | 0 | 5 | 0.0% |
608 | detdet | Assault | 1 | 7 | 14.3% |
2385 | tragic | UFO | 1 | 7 | 14.3% |
332 | bru | Sub | 2 | 14 | 14.3% |
1330 | kep | Sub | 1 | 6 | 16.7% |
2520 | vulki | Escape | 1 | 6 | 16.7% |
2229 | souldriver | Assault | 1 | 6 | 16.7% |
497 | conscious | UFO | 1 | 6 | 16.7% |
793 | duster | Village | 2 | 12 | 16.7% |
1234 | joep | Sub | 1 | 6 | 16.7% |
226 | blackmagik | Escape | 2 | 10 | 20.0% |
941 | festus | UFO | 1 | 5 | 20.0% |
2515 | vulki | Adlernest | 2 | 10 | 20.0% |
968 | flogzero | Escape | 2 | 9 | 22.2% |
299 | brandon | Sub | 2 | 9 | 22.2% |
2238 | souldriver | UFO | 2 | 8 | 25.0% |
2093 | sem | Cipher | 4 | 16 | 25.0% |
1170 | jaytee | Base | 3 | 12 | 25.0% |
351 | caffeine | Password | 3 | 12 | 25.0% |
1478 | mean | UFO | 2 | 8 | 25.0% |
2557 | warrior | Password | 3 | 12 | 25.0% |
2553 | warrior | Escape | 6 | 24 | 25.0% |
377 | cakel | Sub | 6 | 23 | 26.1% |
2175 | silentstorm | Password | 6 | 23 | 26.1% |
2525 | vulki | Village | 5 | 19 | 26.3% |
937 | festus | Password | 7 | 26 | 26.9% |
616 | detdet | Sub | 5 | 18 | 27.8% |
1875 | prowler | Password | 12 | 43 | 27.9% |
545 | cypher | Frostbite | 7 | 25 | 28.0% |
2469 | virkes | Ice | 7 | 25 | 28.0% |
1328 | kep | Password | 2 | 7 | 28.6% |
1204 | jimmy | Cipher | 4 | 14 | 28.6% |
2609 | xill | Assault | 2 | 7 | 28.6% |
2519 | vulki | Cipher | 2 | 7 | 28.6% |
2002 | risk | Sub | 2 | 7 | 28.6% |
1300 | kazz | Adlernest | 8 | 28 | 28.6% |
2470 | virkes | Password | 2 | 7 | 28.6% |
511 | corpse | Password | 5 | 17 | 29.4% |
1606 | nigel | Base | 23 | 77 | 29.9% |
784 | duster | Assault | 3 | 10 | 30.0% |
1464 | mean | Adlernest | 3 | 10 | 30.0% |
1175 | jaytee | Cipher | 3 | 10 | 30.0% |
814 | elsa | Base | 17 | 56 | 30.4% |
713 | donkey | Assault | 11 | 36 | 30.6% |
540 | cypher | Base | 4 | 13 | 30.8% |
1531 | mmbird | Cipher | 5 | 16 | 31.2% |
tmp_heat.sort_values(by="win%", ascending=False).head(50)
Killer | map | round_win | round_guid | win% | |
---|---|---|---|---|---|
2044 | robmaster | UFO | 5 | 5 | 100.0% |
1784 | pimp | Password | 5 | 5 | 100.0% |
1182 | jaytee | Sub | 5 | 5 | 100.0% |
1518 | miles | UFO | 10 | 11 | 90.9% |
1310 | kazz | Password | 15 | 17 | 88.2% |
627 | diego | Cipher | 18 | 21 | 85.7% |
1562 | mooshu | UFO | 12 | 14 | 85.7% |
1169 | jaytee | Assault | 11 | 13 | 84.6% |
1168 | jaytee | Adlernest | 5 | 6 | 83.3% |
787 | duster | Cipher | 5 | 6 | 83.3% |
631 | diego | Password | 5 | 6 | 83.3% |
1993 | risk | Assault | 8 | 10 | 80.0% |
513 | corpse | Sub | 4 | 5 | 80.0% |
554 | cypher | Village | 12 | 15 | 80.0% |
748 | doza | UFO | 4 | 5 | 80.0% |
665 | ding | Assault | 8 | 10 | 80.0% |
1527 | mmbird | Adlernest | 9 | 12 | 75.0% |
336 | bru | UFO | 6 | 8 | 75.0% |
2263 | source | UFO | 9 | 12 | 75.0% |
1319 | kep | Assault | 6 | 8 | 75.0% |
1797 | pingrage | Cipher | 14 | 19 | 73.7% |
1115 | illkilla | Password | 14 | 19 | 73.7% |
2027 | rob | Password | 13 | 18 | 72.2% |
2616 | xill | Password | 5 | 7 | 71.4% |
2653 | yyz | Beach | 10 | 14 | 71.4% |
235 | blackmagik | UFO | 5 | 7 | 71.4% |
291 | brandon | Beach | 29 | 41 | 70.7% |
2654 | yyz | Cipher | 7 | 10 | 70.0% |
1320 | kep | Base | 7 | 10 | 70.0% |
1313 | kazz | Village | 18 | 26 | 69.2% |
2548 | warrior | Assault | 18 | 26 | 69.2% |
1910 | raiser | Sub | 17 | 25 | 68.0% |
768 | druwin | Escape | 27 | 40 | 67.5% |
729 | donkey | UFO | 4 | 6 | 66.7% |
783 | duster | Adlernest | 12 | 18 | 66.7% |
2632 | yeniceri | Assault | 8 | 12 | 66.7% |
727 | donkey | Sub | 22 | 33 | 66.7% |
2448 | vein | Sub | 4 | 6 | 66.7% |
1321 | kep | Beach | 4 | 6 | 66.7% |
1792 | pingrage | Adlernest | 10 | 15 | 66.7% |
2427 | vacs | Adlernest | 4 | 6 | 66.7% |
1778 | pimp | Base | 10 | 15 | 66.7% |
1876 | prowler | Sub | 4 | 6 | 66.7% |
1181 | jaytee | Password | 12 | 18 | 66.7% |
1305 | kazz | Cipher | 8 | 12 | 66.7% |
1029 | fro | UFO | 6 | 9 | 66.7% |
763 | druwin | Adlernest | 39 | 59 | 66.1% |
626 | diego | Beach | 27 | 41 | 65.9% |
1620 | nigel | Password | 44 | 67 | 65.7% |
666 | ding | Base | 21 | 32 | 65.6% |
#Prepare the graph
tmp_heat_pivot = tmp_heat.pivot(index="Killer",columns="map", values="win%")
sns.set(rc={'figure.figsize':(20,25)})
s = sns.heatmap(tmp_heat_pivot, cbar=True, cmap='viridis', annot=True, fmt='.1%')
for t in s.texts: t.set_text(t.get_text()+ "%")
s.tick_params(top=True, labeltop=True)
s.tick_params(axis='x', labelrotation=90)
s.set_xlabel('X-Axis', fontsize=0)
s.set_ylabel('Y-Axis', fontsize=0)
Text(156.453125, 0.5, 'Y-Axis')
tmp_last_seen = stats[["Killer","round_guid","match_date"]].groupby(["Killer"]).agg({'round_guid' : "count",'match_date' : np.max}).copy()
tmp_last_seen.columns = ["Rounds_played", "Last_seen"]
tmp_last_seen = tmp_last_seen[tmp_last_seen["Rounds_played"]>40].sort_values("Last_seen").reset_index()
tmp_last_seen['year'] = pd.DatetimeIndex(tmp_last_seen['Last_seen']).year
tmp_last_seen['month'] = pd.DatetimeIndex(tmp_last_seen['Last_seen']).month
tmp_last_seen[((tmp_last_seen["year"]==2021) & (tmp_last_seen["month"]<12)) | (tmp_last_seen["year"]<2021)]
Killer | Rounds_played | Last_seen | year | month | |
---|---|---|---|---|---|
0 | sonar | 75 | 2020-04-08 21:49:03 | 2020 | 4 |
1 | boydarilla | 67 | 2020-04-24 00:09:12 | 2020 | 4 |
2 | kotip | 78 | 2020-05-10 21:02:57 | 2020 | 5 |
3 | paper | 146 | 2020-05-11 23:27:44 | 2020 | 5 |
4 | oliokath | 169 | 2020-07-30 22:43:17 | 2020 | 7 |
5 | gut | 142 | 2020-08-11 17:25:09 | 2020 | 8 |
6 | dash | 42 | 2020-08-12 23:29:02 | 2020 | 8 |
7 | spuddy | 43 | 2020-08-13 21:43:46 | 2020 | 8 |
8 | sloth | 74 | 2020-08-20 23:16:48 | 2020 | 8 |
9 | aristotle | 127 | 2020-08-30 23:34:07 | 2020 | 8 |
10 | mean | 529 | 2020-09-24 23:11:19 | 2020 | 9 |
11 | dresserwood | 147 | 2020-10-17 22:56:55 | 2020 | 10 |
12 | duster | 282 | 2020-10-25 22:22:36 | 2020 | 10 |
13 | pasek | 139 | 2020-11-01 22:02:50 | 2020 | 11 |
14 | wang | 42 | 2020-11-05 22:16:06 | 2020 | 11 |
15 | knifey | 43 | 2020-11-05 23:06:02 | 2020 | 11 |
16 | scrilla | 98 | 2020-11-12 22:33:46 | 2020 | 11 |
17 | booty | 75 | 2020-11-30 22:21:44 | 2020 | 11 |
18 | caffeine | 295 | 2020-12-04 23:47:49 | 2020 | 12 |
19 | fox | 105 | 2020-12-12 22:43:41 | 2020 | 12 |
20 | nizou | 56 | 2021-01-09 22:00:10 | 2021 | 1 |
21 | scrill4 | 89 | 2021-01-15 05:38:37 | 2021 | 1 |
22 | ceres | 63 | 2021-01-16 22:50:20 | 2021 | 1 |
23 | vodka | 201 | 2021-01-23 04:35:00 | 2021 | 1 |
24 | flogzero | 1238 | 2021-03-18 21:56:18 | 2021 | 3 |
25 | fatihot | 62 | 2021-04-18 22:10:12 | 2021 | 4 |
26 | lasher | 86 | 2021-05-15 00:47:23 | 2021 | 5 |
27 | cash | 158 | 2021-05-17 03:04:28 | 2021 | 5 |
28 | jimmy | 583 | 2021-05-17 04:14:16 | 2021 | 5 |
29 | cliffdark | 491 | 2021-05-22 21:31:50 | 2021 | 5 |
30 | pimp | 352 | 2021-05-24 04:17:06 | 2021 | 5 |
31 | kep | 263 | 2021-06-06 23:37:00 | 2021 | 6 |
32 | kazz | 430 | 2021-06-29 21:33:31 | 2021 | 6 |
33 | blaz | 41 | 2021-07-07 00:39:32 | 2021 | 7 |
34 | kaiser | 66 | 2021-07-14 23:22:19 | 2021 | 7 |
35 | shat | 187 | 2021-08-17 02:16:45 | 2021 | 8 |
36 | naper | 44 | 2021-08-19 04:04:59 | 2021 | 8 |
37 | vis | 119 | 2021-08-20 19:44:55 | 2021 | 8 |
38 | luna | 257 | 2021-08-20 20:39:50 | 2021 | 8 |
39 | tragic | 384 | 2021-08-20 20:39:50 | 2021 | 8 |
40 | virus | 62 | 2021-08-20 20:39:50 | 2021 | 8 |
41 | cypher | 265 | 2021-08-20 20:39:50 | 2021 | 8 |
42 | siluro | 67 | 2021-08-20 20:39:50 | 2021 | 8 |
43 | blox | 48 | 2021-08-21 02:19:21 | 2021 | 8 |
44 | blackmagik | 1192 | 2021-08-22 23:15:39 | 2021 | 8 |
45 | sixers | 45 | 2021-08-23 23:03:04 | 2021 | 8 |
46 | prowler | 1314 | 2021-08-31 04:43:45 | 2021 | 8 |
47 | cky | 227 | 2021-09-02 03:22:35 | 2021 | 9 |
48 | elver | 57 | 2021-09-03 00:01:35 | 2021 | 9 |
49 | biggi | 143 | 2021-09-05 07:10:32 | 2021 | 9 |
50 | gorthrax | 82 | 2021-09-15 03:37:47 | 2021 | 9 |
51 | gatorhead | 74 | 2021-09-16 23:01:12 | 2021 | 9 |
52 | rev9 | 108 | 2021-09-30 21:18:11 | 2021 | 9 |
53 | raiser | 1893 | 2021-10-04 03:09:34 | 2021 | 10 |
54 | shaz | 267 | 2021-10-08 03:35:27 | 2021 | 10 |
55 | jaytee | 456 | 2021-10-11 01:44:57 | 2021 | 10 |
56 | shrek | 53 | 2021-10-21 00:06:30 | 2021 | 10 |
57 | corpse | 665 | 2021-11-06 02:07:55 | 2021 | 11 |
58 | playa | 90 | 2021-11-06 03:11:33 | 2021 | 11 |
59 | utrolig | 153 | 2021-11-06 03:11:33 | 2021 | 11 |
60 | vacs | 282 | 2021-11-10 21:49:38 | 2021 | 11 |
61 | jam | 562 | 2021-11-11 22:31:40 | 2021 | 11 |
62 | vorg | 51 | 2021-11-13 04:20:35 | 2021 | 11 |
63 | sem | 295 | 2021-11-14 19:42:42 | 2021 | 11 |
64 | zed | 44 | 2021-11-21 23:43:57 | 2021 | 11 |
65 | kamizama | 69 | 2021-11-22 23:51:06 | 2021 | 11 |
66 | conscious | 1188 | 2021-11-29 23:48:21 | 2021 | 11 |
tmp_map_times= stats[stats["round_num"] == 2]
shortest_rounds = tmp_map_times[["round_guid","round_time"]].groupby(["round_guid"]).agg({'round_time' : np.min}).sort_values(by="round_time").head(3).index.values
stats[stats["round_guid"].isin(shortest_rounds)][["map", "match_date", "Killer", "side", "game_result", "round_time"]].sort_values(by=["round_time","match_date", "side"])
map | match_date | Killer | side | game_result | round_time | |
---|---|---|---|---|---|---|
47344 | Adlernest | 2021-08-19 22:07:20 | knicks9999 | Defense | LOST | 56 |
47345 | Adlernest | 2021-08-19 22:07:20 | blox | Defense | LOST | 56 |
47352 | Adlernest | 2021-08-19 22:07:20 | biggi | Defense | LOST | 56 |
47353 | Adlernest | 2021-08-19 22:07:20 | festus | Defense | LOST | 56 |
47354 | Adlernest | 2021-08-19 22:07:20 | mika9999 | Defense | LOST | 56 |
47355 | Adlernest | 2021-08-19 22:07:20 | pug9999 | Defense | LOST | 56 |
47346 | Adlernest | 2021-08-19 22:07:20 | ipod | Offense | WON | 56 |
47347 | Adlernest | 2021-08-19 22:07:20 | john_mullins | Offense | WON | 56 |
47348 | Adlernest | 2021-08-19 22:07:20 | raiser | Offense | WON | 56 |
47349 | Adlernest | 2021-08-19 22:07:20 | sem | Offense | WON | 56 |
47350 | Adlernest | 2021-08-19 22:07:20 | cky | Offense | WON | 56 |
47351 | Adlernest | 2021-08-19 22:07:20 | eternal | Offense | WON | 56 |
66039 | Frostbite | 2021-07-15 00:12:24 | ipod | Defense | WON | 62 |
66041 | Frostbite | 2021-07-15 00:12:24 | parcher | Defense | WON | 62 |
66042 | Frostbite | 2021-07-15 00:12:24 | donkey | Defense | WON | 62 |
66043 | Frostbite | 2021-07-15 00:12:24 | gatorhead | Defense | WON | 62 |
66044 | Frostbite | 2021-07-15 00:12:24 | murkey | Defense | WON | 62 |
66045 | Frostbite | 2021-07-15 00:12:24 | fonze | Defense | WON | 62 |
66038 | Frostbite | 2021-07-15 00:12:24 | brandon | Offense | LOST | 62 |
66040 | Frostbite | 2021-07-15 00:12:24 | john_mullins | Offense | LOST | 62 |
66046 | Frostbite | 2021-07-15 00:12:24 | kittens | Offense | LOST | 62 |
66047 | Frostbite | 2021-07-15 00:12:24 | vacs | Offense | LOST | 62 |
66048 | Frostbite | 2021-07-15 00:12:24 | donka | Offense | LOST | 62 |
66049 | Frostbite | 2021-07-15 00:12:24 | nigel | Offense | LOST | 62 |
7660 | Beach | 2020-08-26 23:18:16 | raiser | Defense | LOST | 64 |
7661 | Beach | 2020-08-26 23:18:16 | conscious | Defense | LOST | 64 |
7662 | Beach | 2020-08-26 23:18:16 | donkey | Defense | LOST | 64 |
7663 | Beach | 2020-08-26 23:18:16 | spaztik | Defense | LOST | 64 |
7667 | Beach | 2020-08-26 23:18:16 | donka | Defense | LOST | 64 |
7668 | Beach | 2020-08-26 23:18:16 | fenix | Defense | LOST | 64 |
7664 | Beach | 2020-08-26 23:18:16 | fro | Offense | WON | 64 |
7665 | Beach | 2020-08-26 23:18:16 | john_mullins | Offense | WON | 64 |
7666 | Beach | 2020-08-26 23:18:16 | murkey | Offense | WON | 64 |
7669 | Beach | 2020-08-26 23:18:16 | fonze | Offense | WON | 64 |
7670 | Beach | 2020-08-26 23:18:16 | pingrage | Offense | WON | 64 |
7671 | Beach | 2020-08-26 23:18:16 | rob | Offense | WON | 64 |
tmp_map_times_res = tmp_map_times[["round_time","map","OSP_Kills"]].groupby(["map"]).agg({"round_time": [np.min, np.mean], "OSP_Kills": "mean"})
tmp_map_times_res.columns = ["Fastest(sec)", "Average(min)", "Kills Per Person/Min"]
tmp_map_times_res["Average(min)"] = tmp_map_times_res["Average(min)"]/60
tmp_map_times_res["Kills Per Person/Min"] = tmp_map_times_res["Kills Per Person/Min"]/60
pd.options.display.float_format = '{:.2f}'.format
tmp_map_times_res
Fastest(sec) | Average(min) | Kills Per Person/Min | |
---|---|---|---|
map | |||
Adlernest | 56 | 4.69 | 0.26 |
Assault | 113 | 5.78 | 0.18 |
Base | 85 | 3.94 | 0.15 |
Beach | 64 | 5.31 | 0.20 |
Braundorf | 199 | 4.12 | 0.17 |
Breakout | 208 | 3.64 | 0.14 |
Brewdog | 126 | 4.36 | 0.22 |
Castle | 228 | 3.80 | 0.16 |
Chateau | 98 | 2.75 | 0.12 |
Church | 260 | 4.33 | 0.18 |
Cipher | 82 | 4.96 | 0.25 |
Delivery | 212 | 4.45 | 0.23 |
Escape | 98 | 4.25 | 0.22 |
Frostbite | 62 | 4.43 | 0.21 |
Ice | 87 | 5.64 | 0.24 |
Keep | 132 | 5.51 | 0.25 |
Kungfugrip | 92 | 2.02 | 0.04 |
Market garden | 1009 | 16.82 | 0.28 |
Password | 135 | 6.81 | 0.28 |
Radar | 233 | 5.28 | 0.26 |
Sub | 82 | 3.13 | 0.15 |
Tram | 479 | 15.05 | 0.50 |
Tundra | 99 | 7.00 | 0.25 |
Tunordic | 79 | 6.42 | 0.25 |
UFO | 99 | 6.83 | 0.22 |
Village | 144 | 6.49 | 0.23 |
Blank class is either engineer or (most likely) a medic
tmp_best_perf = stats[stats["round_num"] == 2]
tmp_best_perf = tmp_best_perf["Kills"].sort_values().tail(10)
stats[stats["Kills"].isin(tmp_best_perf)][["map", "match_date", "Killer", "Kills", "class", "round_time"]].sort_values(by=["Kills"], ascending=False)
map | match_date | Killer | Kills | class | round_time | |
---|---|---|---|---|---|---|
315 | Tram | 2020-04-10 00:54:19 | eternal | 43 | L | 1200 |
28373 | Password | 2020-05-10 23:11:16 | bru | 39 | P | 900 |
100642 | Adlernest | 2021-09-12 07:29:49 | parcher | 39 | 600 | |
78023 | Frostbite | 2021-05-12 00:17:51 | ipod | 39 | L | 600 |
61695 | Password | 2021-01-16 22:24:12 | donkey | 39 | P | 900 |
33203 | Password | 2020-10-15 22:28:10 | john_mullins | 39 | L | 878 |
54340 | Adlernest | 2021-12-25 00:17:28 | LitoriousJackson... | 37 | P | 592 |
309 | Tram | 2020-04-10 00:54:19 | source | 37 | P | 1200 |
293 | Tram | 2020-04-10 00:33:31 | murkey | 37 | S | 1200 |
33680 | Adlernest | 2020-10-18 00:34:27 | joep | 37 | P | 600 |
50066 | Ice | 2021-08-30 23:24:26 | fro | 36 | P | 600 |
59769 | Base | 2021-01-04 23:42:02 | john_mullins | 36 | L | 695 |
10517 | Password | 2020-12-17 22:49:29 | fatihot | 36 | P | 900 |
13893 | Ice | 2020-02-27 22:23:21 | source | 36 | L | 575 |
56052 | Adlernest | 2021-02-06 22:58:13 | john_mullins | 36 | 596 | |
66328 | Adlernest | 2021-07-16 22:08:11 | brandon | 36 | P | 600 |
3502 | Tram | 2020-04-03 23:59:16 | kittens | 36 | 1200 | |
2549 | Ice | 2020-04-01 21:08:19 | brandon | 36 | P | 600 |
94035 | Adlernest | 2021-10-20 23:44:52 | warrior | 36 | 600 | |
60293 | Password | 2021-01-08 00:02:39 | john_mullins | 35 | L | 900 |
57033 | Adlernest | 2021-02-16 21:44:22 | fro | 35 | P | 600 |
50276 | Adlernest | 2021-12-01 22:15:55 | ipod | 35 | P | 600 |
103142 | Ice | 2021-09-24 22:08:16 | john_mullins | 35 | P | 600 |
56041 | Adlernest | 2021-02-06 22:46:29 | kittens | 35 | P | 596 |
50707 | Adlernest | 2021-12-02 23:16:29 | ipod | 35 | P | 600 |
4051 | Password | 2020-04-23 22:57:21 | kittens | 35 | 900 | |
3515 | Tram | 2020-04-03 23:59:16 | murkey | 35 | S | 1200 |
3111 | Market garden | 2020-04-02 23:13:33 | source | 35 | 1009 | |
318 | Tram | 2020-04-10 00:54:19 | murkey | 35 | 1200 | |
46799 | Frostbite | 2021-08-17 01:32:56 | druwin | 34 | P | 463 |
32817 | Tunordic | 2020-10-14 22:03:42 | john_mullins | 34 | L | 600 |
80450 | Password | 2021-05-30 01:11:05 | fro | 34 | P | 815 |
86276 | Adlernest | 2021-11-22 23:23:32 | ipod | 34 | P | 600 |
86335 | Ice | 2021-11-24 04:18:33 | ipod | 34 | P | 600 |
305 | Tram | 2020-04-10 00:54:19 | parcher | 34 | 1200 | |
101899 | Escape | 2021-09-18 05:34:41 | murkey | 34 | 600 | |
102180 | Adlernest | 2021-09-19 01:50:15 | john_mullins | 34 | P | 590 |
288 | Tram | 2020-04-10 00:33:31 | donka | 34 | 1200 |
games_over6_players = player_nums[player_nums > 12].index.values
tmp_best_perf_2 = stats[~stats['round_guid'].isin(games_over6_players)]
tmp_best_perf_2 = tmp_best_perf_2["Kills"].sort_values().tail(10)
stats[stats["Kills"].isin(tmp_best_perf_2)][["map", "match_date", "Killer", "Kills", "class", "round_time"]].sort_values(by=["Kills"], ascending=False)
map | match_date | Killer | Kills | class | round_time | |
---|---|---|---|---|---|---|
283 | Tram | 2020-04-10 00:33:31 | source | 41 | S | 1200 |
76956 | Adlernest | 2021-05-07 01:05:20 | biggi | 41 | S | 415 |
28373 | Password | 2020-05-10 23:11:16 | bru | 39 | P | 900 |
78023 | Frostbite | 2021-05-12 00:17:51 | ipod | 39 | L | 600 |
61695 | Password | 2021-01-16 22:24:12 | donkey | 39 | P | 900 |
33203 | Password | 2020-10-15 22:28:10 | john_mullins | 39 | L | 878 |
100642 | Adlernest | 2021-09-12 07:29:49 | parcher | 39 | 600 | |
33680 | Adlernest | 2020-10-18 00:34:27 | joep | 37 | P | 600 |
293 | Tram | 2020-04-10 00:33:31 | murkey | 37 | S | 1200 |
54340 | Adlernest | 2021-12-25 00:17:28 | LitoriousJackson... | 37 | P | 592 |
309 | Tram | 2020-04-10 00:54:19 | source | 37 | P | 1200 |
13893 | Ice | 2020-02-27 22:23:21 | source | 36 | L | 575 |
10517 | Password | 2020-12-17 22:49:29 | fatihot | 36 | P | 900 |
56052 | Adlernest | 2021-02-06 22:58:13 | john_mullins | 36 | 596 | |
59769 | Base | 2021-01-04 23:42:02 | john_mullins | 36 | L | 695 |
3502 | Tram | 2020-04-03 23:59:16 | kittens | 36 | 1200 | |
66328 | Adlernest | 2021-07-16 22:08:11 | brandon | 36 | P | 600 |
2549 | Ice | 2020-04-01 21:08:19 | brandon | 36 | P | 600 |
94035 | Adlernest | 2021-10-20 23:44:52 | warrior | 36 | 600 | |
50066 | Ice | 2021-08-30 23:24:26 | fro | 36 | P | 600 |
player_nums = stats_original["round_guid"].value_counts()
most_players_round_guid = player_nums.head(1)
print("Most players in a single match: ", most_players_round_guid.values[0])
tmp_most_players = stats_original[stats_original['round_guid'].isin(most_players_round_guid.index.values)]
tmp_most_players[["map", "match_date", "Killer", "Kills", "round_time", "OSP_Team"]].sort_values(by=["OSP_Team", "Kills"], ascending=False)
Most players in a single match: 26
map | match_date | Killer | Kills | round_time | OSP_Team | |
---|---|---|---|---|---|---|
253 | Assault | 2020-04-10 00:11:47 | parcher | 9 | 406 | Axis |
257 | Assault | 2020-04-10 00:11:47 | kittens | 9 | 406 | Axis |
263 | Assault | 2020-04-10 00:11:47 | donka | 6 | 406 | Axis |
269 | Assault | 2020-04-10 00:11:47 | mooshu | 6 | 406 | Axis |
254 | Assault | 2020-04-10 00:11:47 | cypher | 5 | 406 | Axis |
255 | Assault | 2020-04-10 00:11:47 | dillweed | 5 | 406 | Axis |
258 | Assault | 2020-04-10 00:11:47 | raiser | 5 | 406 | Axis |
266 | Assault | 2020-04-10 00:11:47 | eternal | 5 | 406 | Axis |
270 | Assault | 2020-04-10 00:11:47 | murkey | 5 | 406 | Axis |
272 | Assault | 2020-04-10 00:11:47 | paper | 4 | 406 | Axis |
275 | Assault | 2020-04-10 00:11:47 | spaztik | 4 | 406 | Axis |
260 | Assault | 2020-04-10 00:11:47 | wang | 1 | 406 | Axis |
252 | Assault | 2020-04-10 00:11:47 | john_mullins | 0 | 406 | Axis |
259 | Assault | 2020-04-10 00:11:47 | source | 11 | 406 | Allies |
267 | Assault | 2020-04-10 00:11:47 | gut | 10 | 406 | Allies |
261 | Assault | 2020-04-10 00:11:47 | blackmagik7inc. | 9 | 406 | Allies |
262 | Assault | 2020-04-10 00:11:47 | caffeine | 9 | 406 | Allies |
273 | Assault | 2020-04-10 00:11:47 | playa | 9 | 406 | Allies |
271 | Assault | 2020-04-10 00:11:47 | nigel | 8 | 406 | Allies |
276 | Assault | 2020-04-10 00:11:47 | spuddy | 7 | 406 | Allies |
264 | Assault | 2020-04-10 00:11:47 | flogzero | 6 | 406 | Allies |
265 | Assault | 2020-04-10 00:11:47 | mean | 5 | 406 | Allies |
268 | Assault | 2020-04-10 00:11:47 | miles | 4 | 406 | Allies |
274 | Assault | 2020-04-10 00:11:47 | prowler | 4 | 406 | Allies |
256 | Assault | 2020-04-10 00:11:47 | deadeye | 1 | 406 | Allies |
277 | Assault | 2020-04-10 00:11:47 | boydarilla | 0 | 406 | Allies |
tmp_mapfh = stats[stats["round_num"] == 2].copy()
tmp_mapfh = tmp_mapfh[~tmp_mapfh['round_guid'].isin(games_over6_players)]
tmp_mapfh = tmp_mapfh.groupby(["round_guid","map","game_result"]).count()["Kills"].reset_index()
tmp_mapfh = tmp_mapfh.groupby(["map","game_result"]).count()["Kills"].reset_index()
tmp_mapfh.columns = ["map","game_result","Count"]
tmp_mapfh = tmp_mapfh.pivot(index="map",columns="game_result", values="Count")
pd.options.display.float_format = '{:.2%}'.format
tmp_mapfh["Draw%"] = tmp_mapfh["FULLHOLD"]/tmp_mapfh["WON"] #or lost, it goes both ways
tmp_mapfh["Draw%"].fillna(0).sort_values()
map Tundra 0.00% Tram 0.00% Brewdog 0.00% Castle 0.00% Chateau 0.00% Church 0.00% Delivery 0.00% Sub 0.96% Base 1.46% Escape 2.25% Adlernest 3.05% Frostbite 3.15% Cipher 3.30% Password 4.24% Beach 9.27% Ice 10.26% UFO 13.04% Assault 13.54% Village 16.44% Keep 25.00% Tunordic 40.00% Name: Draw%, dtype: float64
This is an attempt to see improvement in players over time
pd.options.display.float_format = '{:.1f}'.format
tmp_improv = stats[stats["round_num"] == 2].copy()
tmp_improv = tmp_improv[~tmp_improv["OSP_Team"].isin(['0',''])]
tmp_improv = tmp_improv[tmp_improv["Killer"].isin(tmp_games_filt.index.values)]
tmp_improv = tmp_improv.groupby(["Killer", "year", "quarter"]) \
.agg({"OSP_Damage_Given":"sum", "Kills": "sum", "Deaths": "sum", "round_time" :"sum", "round_win" : "sum", "round_guid" : "count"}) \
.reset_index()
tmp_improv["year.q"] = tmp_improv["year"].astype(str) + "." + tmp_improv["quarter"].divide(.04).astype(int).astype(str)
tmp_improv["KDR"] = tmp_improv["Kills"]/tmp_improv["Deaths"]
tmp_improv["DPM"] = tmp_improv["OSP_Damage_Given"]/(tmp_improv["round_time"]/60)
tmp_improv["win%"] = tmp_improv["round_win"]/tmp_improv["round_guid"]
tmp_improv_pivot = tmp_improv.pivot(index="Killer", columns="year.q", values = ["KDR","DPM"])
tmp_improv_pivot= tmp_improv_pivot[tmp_improv_pivot["DPM"]["2021.75"].notna()] #seed out people who quit
kdr_slopes = {}
dpm_slopes = {}
for player, values in tmp_improv_pivot.iterrows():
mean_kdr = values["KDR"].mean()
values["KDR"].fillna(mean_kdr, inplace=True)
kdr_x = values["KDR"].index.values.astype(float)
kdr_y = values["KDR"].values
kdr_slopes[player] = np.polyfit(kdr_x, kdr_y,1)[0]
mean_dpm = values["DPM"].mean()
values["DPM"].fillna(mean_dpm, inplace=True)
dpm_x = values["DPM"].index.values.astype(float)
dpm_y = values["DPM"].values
dpm_slopes[player] = np.polyfit(dpm_x, dpm_y,1)[0]
kdr_df = pd.DataFrame.from_dict(kdr_slopes, orient='index', columns = ["kdr_slope"])
dpm_df = pd.DataFrame.from_dict(dpm_slopes, orient='index', columns = ["dpm_slope"])
pd.options.display.float_format = '{:.3f}'.format
tmp_improv_pivot_kdr = tmp_improv_pivot["KDR"].join(kdr_df)
tmp_improv_pivot_kdr[tmp_improv_pivot_kdr["kdr_slope"]>0.02].sort_values(by=["kdr_slope"], ascending=False)
2020.100 | 2020.25 | 2020.50 | 2020.75 | 2021.100 | 2021.25 | 2021.50 | 2021.75 | kdr_slope | |
---|---|---|---|---|---|---|---|---|---|
Killer | |||||||||
miles | 0.957 | 0.650 | 0.896 | 0.933 | 1.074 | 1.164 | 1.521 | 1.204 | 0.350 |
rob | 0.417 | 0.977 | 0.977 | 0.937 | 1.032 | 0.902 | 1.500 | 1.073 | 0.335 |
john_mullins | 1.234 | 0.490 | 0.621 | 1.207 | 1.431 | 1.250 | 1.186 | 1.324 | 0.331 |
silentstorm | 0.393 | 0.802 | 0.802 | 0.802 | 0.940 | 0.792 | 0.874 | 1.007 | 0.229 |
mooshu | 0.749 | 0.360 | 0.644 | 0.669 | 0.844 | 0.900 | 0.871 | 0.865 | 0.221 |
doza | 1.304 | 1.113 | 0.763 | 0.593 | 1.257 | 1.359 | 1.275 | 1.239 | 0.155 |
jam | 1.355 | 1.538 | 1.538 | 1.538 | 1.501 | 1.401 | 1.820 | 1.612 | 0.130 |
virkes | 0.781 | 0.781 | 0.781 | 0.409 | 0.824 | 0.781 | 1.043 | 0.848 | 0.112 |
donkey | 1.226 | 0.872 | 1.157 | 1.152 | 1.108 | 1.308 | 1.300 | 1.132 | 0.096 |
fonze | 0.881 | 0.896 | 0.656 | 0.986 | 0.925 | 0.965 | 0.905 | 0.951 | 0.071 |
cakel | 0.620 | 0.510 | 0.588 | 0.567 | 0.600 | 0.626 | 0.587 | 0.690 | 0.052 |
conscious | 0.767 | 0.819 | 0.765 | 0.818 | 0.819 | 0.851 | 0.879 | 0.831 | 0.049 |
robmaster | 0.966 | 0.966 | 0.966 | 0.966 | 0.785 | 0.968 | 1.009 | 1.103 | 0.043 |
ipod | 1.034 | 1.034 | 1.034 | 1.034 | 1.185 | 0.667 | 1.112 | 1.172 | 0.027 |
corpse | 0.932 | 1.019 | 0.912 | 0.750 | 0.943 | 0.949 | 0.953 | 1.000 | 0.023 |
tmp_improv_pivot_dpm = tmp_improv_pivot["DPM"].join(dpm_df)
tmp_improv_pivot_dpm[tmp_improv_pivot_dpm["dpm_slope"]>0.025].sort_values(by=["dpm_slope"], ascending=False)
2020.100 | 2020.25 | 2020.50 | 2020.75 | 2021.100 | 2021.25 | 2021.50 | 2021.75 | dpm_slope | |
---|---|---|---|---|---|---|---|---|---|
Killer | |||||||||
miles | 438.269 | 310.292 | 386.837 | 457.548 | 550.269 | 520.125 | 545.217 | 585.355 | 136.991 |
john_mullins | 738.901 | 392.876 | 485.899 | 741.356 | 859.891 | 720.545 | 636.479 | 763.156 | 121.561 |
silentstorm | 252.664 | 369.296 | 369.296 | 369.296 | 412.597 | 339.257 | 397.625 | 444.335 | 69.170 |
mooshu | 365.120 | 232.480 | 345.010 | 468.434 | 451.595 | 395.688 | 427.396 | 395.331 | 68.194 |
conscious | 304.481 | 375.517 | 339.043 | 384.003 | 375.517 | 431.215 | 355.988 | 438.369 | 52.750 |
yyz | 624.040 | 624.040 | 624.040 | 596.387 | 519.599 | 624.040 | 624.040 | 756.134 | 38.369 |
nigel | 461.334 | 603.504 | 556.013 | 532.664 | 586.037 | 534.678 | 527.207 | 620.218 | 33.817 |
yeniceri | 228.491 | 282.257 | 282.257 | 282.257 | 324.583 | 293.664 | 265.319 | 299.226 | 23.989 |
donkey | 633.793 | 418.333 | 567.969 | 628.135 | 554.213 | 576.747 | 584.162 | 580.403 | 22.564 |
rob | 347.712 | 448.001 | 448.001 | 532.803 | 509.211 | 421.271 | 445.232 | 431.780 | 22.067 |
doza | 513.143 | 477.919 | 467.009 | 319.481 | 540.565 | 510.456 | 509.639 | 485.142 | 19.694 |
fonze | 387.180 | 381.850 | 308.635 | 377.033 | 416.289 | 424.204 | 379.767 | 379.839 | 17.871 |
robmaster | 444.375 | 444.375 | 444.375 | 444.375 | 353.390 | 480.827 | 438.035 | 505.247 | 17.068 |
druwin | 690.514 | 704.830 | 704.830 | 704.830 | 735.950 | 701.606 | 646.935 | 749.145 | 7.823 |
festus | 336.309 | 363.163 | 370.572 | 375.822 | 375.447 | 380.802 | 317.077 | 372.566 | 2.246 |
spaztik | 413.281 | 360.314 | 429.649 | 479.164 | 452.064 | 427.836 | 396.019 | 394.237 | 1.729 |
cakel | 257.764 | 270.133 | 284.831 | 291.964 | 293.877 | 268.555 | 266.199 | 267.265 | 0.056 |
tmp_averages = stats[stats["round_num"] == 2].copy()
tmp_averages = tmp_averages[tmp_averages["OSP_Damage_Given"]>0]
tmp_averages = tmp_averages[tmp_averages["OSP_Kills"]<50]
tmp_averages = tmp_averages[tmp_averages["Killer"].isin(tmp_games_filt.index.values)]
tmp_averages = tmp_averages.groupby(["Killer"]).agg({"OSP_Damage_Given": "sum",
"OSP_Damage_Received": "sum",
"round_guid" : "count",
"round_time": "sum",
"OSP_Kills": "sum",
"OSP_Deaths": "sum",
"OSP_Suicides": "sum",
"AdjScore": "mean"})
tmp_averages["KDR"] = tmp_averages["OSP_Kills"]/tmp_averages["OSP_Deaths"]
tmp_averages["DPM"] = tmp_averages["OSP_Damage_Given"]/(tmp_averages["round_time"]/60)
tmp_averages["DPK"] = tmp_averages["OSP_Damage_Given"]/tmp_averages["OSP_Kills"]
tmp_averages["DPD"] = tmp_averages["OSP_Damage_Received"]/tmp_averages["OSP_Deaths"]
tmp_averages["SPD%"] = tmp_averages["OSP_Suicides"]/tmp_averages["OSP_Deaths"]*100
pd.options.display.float_format = '{:.1f}'.format
tmp_averages
OSP_Damage_Given | OSP_Damage_Received | round_guid | round_time | OSP_Kills | OSP_Deaths | OSP_Suicides | AdjScore | KDR | DPM | DPK | DPD | SPD% | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|
Killer | |||||||||||||
blackmagik | 1602745 | 1371946 | 583 | 183880 | 7368 | 8062 | 2062 | 10.5 | 0.9 | 523.0 | 217.5 | 170.2 | 25.6 |
brandon | 1914414 | 1203885 | 459 | 140943 | 8559 | 6518 | 2411 | 8.0 | 1.3 | 815.0 | 223.7 | 184.7 | 37.0 |
bru | 3779929 | 3259296 | 1215 | 381348 | 17991 | 19793 | 5179 | 11.2 | 0.9 | 594.7 | 210.1 | 164.7 | 26.2 |
caffeine | 551797 | 424220 | 148 | 50782 | 2252 | 2840 | 939 | 9.2 | 0.8 | 652.0 | 245.0 | 149.4 | 33.1 |
cakel | 2547027 | 4396417 | 1758 | 553025 | 13239 | 23506 | 3825 | 10.5 | 0.6 | 276.3 | 192.4 | 187.0 | 16.3 |
cliffdark | 617497 | 613806 | 241 | 70903 | 2842 | 3825 | 741 | 10.5 | 0.7 | 522.5 | 217.3 | 160.5 | 19.4 |
conscious | 1132064 | 1581260 | 583 | 182985 | 5683 | 7663 | 1157 | 11.5 | 0.7 | 371.2 | 199.2 | 206.3 | 15.1 |
corpse | 757234 | 853390 | 328 | 98025 | 3784 | 4313 | 710 | 12.6 | 0.9 | 463.5 | 200.1 | 197.9 | 16.5 |
cypher | 301086 | 415511 | 135 | 43801 | 1409 | 2228 | 348 | 12.9 | 0.6 | 412.4 | 213.7 | 186.5 | 15.6 |
deadeye | 2104054 | 3874917 | 1503 | 481247 | 10418 | 21117 | 1552 | 9.6 | 0.5 | 262.3 | 202.0 | 183.5 | 7.3 |
detdet | 628038 | 722741 | 251 | 76302 | 3304 | 3252 | 675 | 11.1 | 1.0 | 493.9 | 190.1 | 222.2 | 20.8 |
diego | 481307 | 630117 | 265 | 77549 | 2118 | 3272 | 474 | 8.5 | 0.6 | 372.4 | 227.2 | 192.6 | 14.5 |
dillweed | 988431 | 1994625 | 755 | 242510 | 4880 | 10731 | 940 | 12.0 | 0.5 | 244.6 | 202.5 | 185.9 | 8.8 |
ding | 721303 | 893675 | 353 | 108367 | 3804 | 4543 | 751 | 13.1 | 0.8 | 399.4 | 189.6 | 196.7 | 16.5 |
donka | 4369870 | 4668699 | 1722 | 539669 | 21843 | 24113 | 4272 | 12.2 | 0.9 | 485.8 | 200.1 | 193.6 | 17.7 |
donkey | 3085498 | 2324775 | 999 | 311205 | 14791 | 13823 | 4421 | 10.1 | 1.1 | 594.9 | 208.6 | 168.2 | 32.0 |
doza | 2450289 | 2463225 | 931 | 287217 | 13199 | 10991 | 3466 | 11.2 | 1.2 | 511.9 | 185.6 | 224.1 | 31.5 |
druwin | 1654629 | 1106871 | 439 | 137152 | 7482 | 5849 | 2295 | 8.2 | 1.3 | 723.9 | 221.1 | 189.2 | 39.2 |
duster | 195200 | 405149 | 139 | 44489 | 1012 | 1992 | 123 | 11.8 | 0.5 | 263.3 | 192.9 | 203.4 | 6.2 |
elsa | 2240594 | 1828086 | 744 | 235681 | 9818 | 10541 | 3714 | 9.1 | 0.9 | 570.4 | 228.2 | 173.4 | 35.2 |
eternal | 2830706 | 2801590 | 1079 | 335958 | 14422 | 15986 | 3073 | 11.8 | 0.9 | 505.5 | 196.3 | 175.3 | 19.2 |
festus | 1193781 | 1505599 | 667 | 199267 | 5896 | 8814 | 2310 | 10.2 | 0.7 | 359.5 | 202.5 | 170.8 | 26.2 |
firehot | 484254 | 1582748 | 587 | 184288 | 2615 | 7724 | 528 | 9.4 | 0.3 | 157.7 | 185.2 | 204.9 | 6.8 |
flogzero | 1773105 | 1747287 | 617 | 196190 | 9088 | 8398 | 1840 | 14.9 | 1.1 | 542.3 | 195.1 | 208.1 | 21.9 |
fonze | 3944732 | 4840515 | 1930 | 611738 | 20205 | 23955 | 3474 | 10.5 | 0.8 | 386.9 | 195.2 | 202.1 | 14.5 |
fro | 5606057 | 3528873 | 1556 | 487256 | 25882 | 19018 | 8866 | 7.0 | 1.4 | 690.3 | 216.6 | 185.6 | 46.6 |
illkilla | 1197349 | 1208940 | 569 | 173992 | 6066 | 7466 | 1450 | 11.7 | 0.8 | 412.9 | 197.4 | 161.9 | 19.4 |
ipod | 3047761 | 2674142 | 961 | 290783 | 14651 | 12980 | 3419 | 10.4 | 1.1 | 628.9 | 208.0 | 206.0 | 26.3 |
jam | 922673 | 718231 | 280 | 86297 | 4867 | 3415 | 1192 | 9.7 | 1.4 | 641.5 | 189.6 | 210.3 | 34.9 |
jaytee | 837338 | 556692 | 227 | 77125 | 3419 | 3560 | 1026 | 7.2 | 1.0 | 651.4 | 244.9 | 156.4 | 28.8 |
jimmy | 883437 | 710812 | 291 | 88957 | 3938 | 4294 | 1015 | 8.6 | 0.9 | 595.9 | 224.3 | 165.5 | 23.6 |
joep | 1205800 | 775564 | 349 | 106377 | 5303 | 4863 | 2222 | 4.9 | 1.1 | 680.1 | 227.4 | 159.5 | 45.7 |
john_mullins | 7668705 | 5440332 | 1987 | 620317 | 34592 | 31157 | 11919 | 7.8 | 1.1 | 741.8 | 221.7 | 174.6 | 38.3 |
kazz | 396787 | 515294 | 213 | 66468 | 2173 | 2788 | 675 | 8.2 | 0.8 | 358.2 | 182.6 | 184.8 | 24.2 |
kep | 165481 | 327887 | 131 | 41227 | 829 | 1724 | 130 | 9.9 | 0.5 | 240.8 | 199.6 | 190.2 | 7.5 |
kittens | 5736464 | 4483278 | 1640 | 507628 | 27105 | 25214 | 7090 | 11.7 | 1.1 | 678.0 | 211.6 | 177.8 | 28.1 |
luna | 396053 | 273448 | 129 | 39531 | 1955 | 1645 | 312 | 9.6 | 1.2 | 601.1 | 202.6 | 166.2 | 19.0 |
mean | 566222 | 725457 | 262 | 83443 | 2695 | 3263 | 334 | 10.2 | 0.8 | 407.1 | 210.1 | 222.3 | 10.2 |
miles | 2019706 | 2132441 | 835 | 258379 | 10176 | 11031 | 2201 | 9.3 | 0.9 | 469.0 | 198.5 | 193.3 | 20.0 |
mmbird | 157465 | 301726 | 125 | 38091 | 810 | 1726 | 104 | 11.3 | 0.5 | 248.0 | 194.4 | 174.8 | 6.0 |
mooshu | 3201933 | 3817601 | 1495 | 468700 | 16662 | 21235 | 4328 | 11.7 | 0.8 | 409.9 | 192.2 | 179.8 | 20.4 |
murkey | 5162460 | 3652470 | 1394 | 436206 | 25358 | 18947 | 5701 | 13.8 | 1.3 | 710.1 | 203.6 | 192.8 | 30.1 |
nigel | 3709980 | 3590852 | 1287 | 396576 | 18766 | 19263 | 4310 | 12.7 | 1.0 | 561.3 | 197.7 | 186.4 | 22.4 |
parcher | 4539290 | 4486460 | 1557 | 489480 | 24202 | 20527 | 4045 | 12.4 | 1.2 | 556.4 | 187.6 | 218.6 | 19.7 |
pimp | 390202 | 396227 | 176 | 57839 | 2045 | 2151 | 503 | 10.6 | 1.0 | 404.8 | 190.8 | 184.2 | 23.4 |
pingrage | 382954 | 436595 | 185 | 57455 | 1921 | 2524 | 580 | 9.3 | 0.8 | 399.9 | 199.4 | 173.0 | 23.0 |
prowler | 1083454 | 1658213 | 652 | 207762 | 5266 | 9087 | 1288 | 11.4 | 0.6 | 312.9 | 205.7 | 182.5 | 14.2 |
raiser | 2616512 | 2022312 | 943 | 295281 | 11618 | 12049 | 4171 | 10.4 | 1.0 | 531.7 | 225.2 | 167.8 | 34.6 |
reker | 1090325 | 1377576 | 576 | 181436 | 5389 | 7682 | 1412 | 13.2 | 0.7 | 360.6 | 202.3 | 179.3 | 18.4 |
risk | 525165 | 358041 | 177 | 54173 | 2554 | 2050 | 1143 | 4.4 | 1.2 | 581.7 | 205.6 | 174.7 | 55.8 |
rob | 1831373 | 1726792 | 759 | 235796 | 8867 | 9608 | 2750 | 8.0 | 0.9 | 466.0 | 206.5 | 179.7 | 28.6 |
robmaster | 1510504 | 1715333 | 702 | 219581 | 7725 | 9064 | 1975 | 9.9 | 0.9 | 412.7 | 195.5 | 189.2 | 21.8 |
sem | 408727 | 439692 | 148 | 46549 | 1959 | 1960 | 361 | 9.5 | 1.0 | 526.8 | 208.6 | 224.3 | 18.4 |
shaz | 280546 | 307214 | 135 | 42500 | 1200 | 1645 | 259 | 6.6 | 0.7 | 396.1 | 233.8 | 186.8 | 15.7 |
silentstorm | 1545721 | 1686973 | 763 | 231697 | 8139 | 9625 | 2608 | 10.3 | 0.8 | 400.3 | 189.9 | 175.3 | 27.1 |
souldriver | 745345 | 1439832 | 544 | 170502 | 3854 | 7205 | 568 | 7.9 | 0.5 | 262.3 | 193.4 | 199.8 | 7.9 |
source | 4435040 | 3148107 | 1361 | 424150 | 22609 | 17735 | 5893 | 11.3 | 1.3 | 627.4 | 196.2 | 177.5 | 33.2 |
spaztik | 2912146 | 2933551 | 1293 | 409321 | 14344 | 17449 | 3368 | 9.7 | 0.8 | 426.9 | 203.0 | 168.1 | 19.3 |
tragic | 499609 | 490437 | 191 | 60675 | 2665 | 2789 | 761 | 11.8 | 1.0 | 494.1 | 187.5 | 175.8 | 27.3 |
vacs | 174223 | 343146 | 142 | 43269 | 918 | 1773 | 321 | 8.1 | 0.5 | 241.6 | 189.8 | 193.5 | 18.1 |
vein | 403514 | 479507 | 170 | 50029 | 2080 | 2092 | 481 | 9.9 | 1.0 | 483.9 | 194.0 | 229.2 | 23.0 |
virkes | 253606 | 318881 | 125 | 39166 | 1242 | 1632 | 276 | 11.4 | 0.8 | 388.5 | 204.2 | 195.4 | 16.9 |
vulki | 199083 | 374750 | 149 | 46710 | 1056 | 1963 | 120 | 8.0 | 0.5 | 255.7 | 188.5 | 190.9 | 6.1 |
warrior | 1348145 | 910865 | 423 | 133094 | 6591 | 5160 | 1635 | 12.6 | 1.3 | 607.8 | 204.5 | 176.5 | 31.7 |
xill | 793760 | 1028430 | 346 | 110194 | 4279 | 4999 | 446 | 12.2 | 0.9 | 432.2 | 185.5 | 205.7 | 8.9 |
yeniceri | 710238 | 1153541 | 476 | 147239 | 3816 | 5901 | 452 | 9.2 | 0.6 | 289.4 | 186.1 | 195.5 | 7.7 |
yyz | 405931 | 471276 | 161 | 46150 | 2042 | 2252 | 548 | 9.5 | 0.9 | 527.8 | 198.8 | 209.3 | 24.3 |
sns.set(rc={'figure.figsize':(12,1)})
sns.boxplot(data=tmp_averages[["KDR"]], orient="h", palette="Set2")
<AxesSubplot:>
sns.boxplot(data=tmp_averages[["DPK"]], orient="h", palette="Set2")
<AxesSubplot:>
sns.boxplot(data=tmp_averages[["DPD"]], orient="h", palette="Set2")
<AxesSubplot:>
sns.boxplot(data=tmp_averages[["SPD%"]], orient="h", palette="Set2")
<AxesSubplot:>
sns.boxplot(data=tmp_averages[["AdjScore"]], orient="h", palette="Set2")
<AxesSubplot:>