# Python-3-Skript zum Auslesen und Auswerten von Daten zu internatonal tätigen Schweizer Fussballspielern.
# Skript: Mathias Born
import requests
from bs4 import BeautifulSoup
from time import sleep, strftime
from random import randint
from os import path
import csv
import re
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
plt.style.use('fivethirtyeight')
plt.rcParams['pdf.fonttype'] = 42
%matplotlib inline
from dateutil.relativedelta import relativedelta
import ast
import warnings
warnings.filterwarnings('ignore')
import mpld3
import folium
import locale
headers = {'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.95 Safari/537.36'}
# Eine Liste mit den europäischen Ligen wird kreiert. Diese benötigen wir später fürs automatisierte
# Auslesen der Gastarbeiter in den einzelnen Ligen.
ligen = list()
for i in range(1,4):
temp_liga = requests.get('http://www.transfermarkt.de/wettbewerbe/europa/wettbewerbe?page=' + str(i) + '&plus=1', headers=headers)
temp_liga = BeautifulSoup(temp_liga.text, 'html.parser')
temp_liga = temp_liga.find('div', {'class':'responsive-table'})
temp_liga = temp_liga.find_all('a')
for liga in temp_liga:
if liga.has_attr('href'):
liga = (liga['href'])
if re.search(r'/startseite/wettbewerb/[A-Z]{1,3}1', liga):
ligen.append(re.search(r'/startseite/wettbewerb/([A-Z]{1,3}1)', liga).group(1))
sleep(5)
ligen.append('FARO')
ligen.remove('C1')
# Falls die Daten noch nicht vorliegen: Zuerst werden die Listen mit den Gastarbeitern
# für jede Saison zwischen 1992 und 2016 ausgelesen.
# Extrahiert wird der Spielername und die URL zu den Detailinfos.
if path.isfile('daten/linkdict.csv'):
if path.isfile('daten/jahrbuch.csv'):
linkdict = dict()
jahrbuch = dict()
# Öffne die vorhandenen Daten mit den Links.
with open('daten/linkdict.csv', 'r') as csv_file:
reader = csv.reader(csv_file)
for key, value in reader:
linkdict[key] = value
# Öffne das vorhandene Jahrbuch.
with open('daten/jahrbuch.csv', 'r') as csv_file:
reader = csv.reader(csv_file)
for key, value in reader:
jahrbuch[key] = ast.literal_eval(value)
else:
linkdict = dict()
jahrbuch = dict()
for jahr in range(1992,2017):
temp_ligen = dict()
print(jahr)
for liga in ligen:
temp_schüttelerliste = list()
temp_namensliste = list()
url = 'http://www.transfermarkt.de/premier-league/gastarbeiterdetail/wettbewerb/' + liga + '?saison_id=' + str(jahr) + '&land_id=148'
response = requests.get(url, headers=headers)
transfermarkt_soup = BeautifulSoup(response.text, 'html.parser')
temp_gastarbeiter = transfermarkt_soup.findAll('td',{'class':'hauptlink'})
if len(temp_gastarbeiter) == 0:
pass
else:
for schütteler in temp_gastarbeiter:
try:
schüttelername = schütteler.find('a').text
schüttelerurl = 'http://www.transfermarkt.de' + schütteler.find('a')['href']
linkdict[schüttelername] = schüttelerurl
temp_schüttelerliste.append(schüttelername)
temp_ligen[liga] = temp_schüttelerliste
except:
pass
jahrbuch[jahr] = temp_ligen
sleep(randint(2,14))
sleep(randint(33,99))
# Die Daten werden lokal abgespeichert, so dass sie später nicht nochmal geladen werden müssen.
with open('daten/linkdict.csv', 'w') as csv_file:
writer = csv.writer(csv_file)
for key, value in linkdict.items():
writer.writerow([key, value])
with open('daten/jahrbuch.csv', 'w') as csv_file:
writer = csv.writer(csv_file)
for key, value in jahrbuch.items():
writer.writerow([key, value])
# Nun werden die Informationen zu den einzelnen Gastarbeitern heruntergeladen und extrahiert.
# Dieser Vorgang dauert sehr lange. Er wird nur ausgeführt, wenn noch keine entsprechenden Daten
# vorhanden sind. Liegen solche vor, werden die vorhandenen Daten geladen.
kat_spielerdaten = ['Geburtsdatum', 'Geburtsort', 'Größe', 'Nationalität',
'Position', 'Fuß', 'Spielerberater', 'Im Team seit',
'Vertrag bis', 'Ausrüster', 'Schuhmodell']
kat_zusatz = ['Aktueller Verein', 'Aktueller Marktwert', 'Nationalmannschaft', 'Länderspiele', 'Jugendvereine', 'Link Leistungsdaten']
kat_socialmedia = ['Twitter', 'Facebook', 'Instagram', 'Offizielle Homepage']
# Prüfen, ob bereits Daten vorhanden sind.
if path.isfile("daten/spielerdetails.csv"):
df = pd.read_csv('output/df.csv')
df.index = df['Unnamed: 0']
del df['Unnamed: 0']
df.head()
transfernummer = list()
for i in range(len(df.columns) - len(kat_spielerdaten) - len(kat_socialmedia) - len(kat_zusatz)):
transfernummer.append('Transfer_' + str(i + 1))
else:
spielerdetails = dict()
for spieler in linkdict:
if path.isfile('daten/' + spieler + '.html'):
with open('daten/' + spieler + '.html', 'r') as f:
response = f.read()
soup_spieler = BeautifulSoup(response, 'html.parser')
else:
sleep(randint(4,120))
# Herunterladen der Spieler-Daten von Transfermarkt.
url = linkdict[spieler]
response = requests.get(url, headers=headers)
soup_spieler = BeautifulSoup(response.text, 'html.parser')
# Die Webseite wird für spätere Arbeiten abgespeichert.
with open('daten/' + spieler + '.html', 'w') as f:
f.write(str(soup_spieler))
# Auslesen der Basisinformationen aus der ersten Tabelle.
spielerdaten = soup_spieler.find('table',{'class':'auflistung'})
temp_zeile = list()
for angabe in kat_spielerdaten:
try:
temp_daten = spielerdaten.find('th', text= angabe + ':').nextSibling.nextSibling.text.replace('\t', '').replace('\xa0', ' ').strip().replace(' ', '/ ')
temp_zeile.append(temp_daten)
except:
temp_zeile.append('')
# Hack für den Spezialfall des aktuellen Vereins.
for angabe in kat_zusatz:
try:
if angabe == 'Aktueller Verein':
temp_daten = soup_spieler.find('span', {'itemprop':"affiliation"}).text
elif angabe == 'Aktueller Marktwert':
temp_daten = soup_spieler.find('div', {'class':"dataMarktwert"}).text.strip()
temp_daten = re.match(r'\d*,\d*.*€', test).group(0)
elif angabe == 'Länderspiele':
länderspiele = soup_spieler.find('span', {'class':'dataItem'}, text='Länderspiele/Tore:').next.next.next.text
temp = re.match(r'(\d*)/(\d*)', länderspiele)
länderspiele = temp.group(1)
länderspiele_tore = temp.group(2)
temp_daten = [länderspiele, länderspiele_tore]
elif angabe == 'Nationalmannschaft':
temp_daten = soup_spieler.find('p', {'class':'notTablet forMobile'}).next.next.next.next.next.find('a').text
elif angabe == 'Jugendvereine':
temp_daten = soup_spieler.find('span', {'class':'headerueberschrift'}, text='Jugendvereine').next.next.next.next.text.strip()
elif angabe == 'Link Leistungsdaten':
temp_daten = soup_spieler.find('a', text='Zu den kompletten Leistungsdaten')['href']
temp_daten = 'http://www.transfermarkt.de' + temp_daten
temp_zeile.append(temp_daten)
except:
temp_zeile.append('')
for angabe in kat_socialmedia:
try:
temp_socialmedia = spielerdaten.find('th', text='Social Media:').nextSibling.nextSibling.find('a', title=angabe)['href']
temp_zeile.append(temp_socialmedia)
except:
temp_zeile.append('')
# Auslesen der Informationen zu den Transfers (2. Tabelle)
try:
soup_transfers = soup_spieler.find('div', {'class': 'box transferhistorie'}).find('table').find('tbody')
soup_transfers = soup_transfers.find_all('tr', {'class': 'zeile-transfer'})
except:
soup_transfers = []
for t in reversed(range(len(soup_transfers))):
try:
temp_tds = soup_transfers[t].find_all('td')
except:
temp_tds = []
try:
temp_saison = temp_tds[0].text
except:
temp_saison = ''
try:
temp_datum = temp_tds[1].text
except:
temp_datum = ''
try:
temp_abgebend = temp_tds[5].find('a').text
except:
temp_abgebend = ''
try:
temp_land1 = temp_tds[3].find('img')['alt']
except:
temp_land1 = ''
try:
temp_aufnehmend = temp_tds[9].find('a').text
except:
temp_aufnehmend = ''
try:
temp_land2 = temp_tds[7].find('img')['alt']
except:
temp_land2 = ''
try:
temp_marktwert = temp_tds[10].text
except:
temp_marktwert = ''
try:
temp_ablöse = temp_tds[11].text
except:
temp_ablöse = ''
#Zusammensetzen der gesammelten Informationen.
temp_transfers = [temp_saison, temp_datum, temp_abgebend, temp_land1, temp_aufnehmend, temp_land2, temp_marktwert, temp_ablöse]
temp_zeile.append(temp_transfers)
spielerdetails[spieler] = temp_zeile
with open('daten/spielerdetails.csv', 'w') as csv_file:
writer = csv.writer(csv_file)
for key, value in spielerdetails.items():
writer.writerow([key, value])
# Einlesen der Daten in Pandas.
df = pd.DataFrame.from_dict(spielerdetails, orient='index')
# Anpassen der Namen der einzelnen Spalten.
transfernummer = list()
for i in range(len(df.columns) - len(kat_spielerdaten) - len(kat_socialmedia) - len(kat_zusatz)):
transfernummer.append('Transfer_' + str(i + 1))
df.columns = kat_spielerdaten + kat_zusatz + kat_socialmedia + transfernummer
# Konvertieren der Angaben im Dataframe
df['Größe'] = df['Größe'].str.replace(',','.')
df['Größe'] = df['Größe'].str.replace('m','')
pd.options.display.max_columns = 50
df.to_csv('output/df.csv')
df.to_excel('output/df.xlsx')
df.to_json('output/df.json')
# Nun haben wir die folgenden Daten (Auszug mit den ersten paar Spielern).
df.head(5)
# Zur Kontrolle: Anzahl Links zu Spielerseiten sowie Anzahl extrahierter Spieler. Bei Bedarf
# können die fehlenden Spieler manuell importiert werden.
print('Anzahl Links:', len(linkdict))
print('Anzahl extrahierter Profile:', len(df))
temp_linkdict = linkdict
for row in df.index:
if row in temp_linkdict:
temp_linkdict.pop(row, None)
print('Wegen Fehlern wurden nicht einbezogen:', ', '.join(temp_linkdict.keys()))
# To do: Aleksandar Prijovic fehlt.
df[df.index.str.contains("Aleksandar")]
# Welches ist der grösste Spieler?
df[df['Größe'] == df['Größe'].max()]
# Wie viele CH-Spieler gibts pro Saison in allen ausländischen Ligen?
internationaleprojahr = dict()
for jahr in jahrbuch.keys():
counter = 0
#jahr = int(jahr)
for liga in jahrbuch[jahr]:
counter = counter + len(jahrbuch[jahr][liga])
internationaleprojahr[jahr] = counter
df_internationaleprojahr = pd.DataFrame.from_dict(internationaleprojahr, orient='index')
df_internationaleprojahr.columns = ['Anzahl Schweizer Internationale']
df_internationaleprojahr.sort_index(ascending=True, inplace=True)
df_internationaleprojahr
fig, ax = plt.subplots(figsize=(14,8))
df_internationaleprojahr.plot(kind='bar', ax=ax, color='darkred')
plt.title('Schweizer in ausländischen Erstmannschaften')
plt.xlabel('')
plt.ylabel('')
plt.tight_layout()
plt.show()
fig.savefig('output/internationaleprojahr.pdf')
fig.savefig('output/internationaleprojahr.png')
# Wie viele Schweizer gibts pro Jahr in den fünf Topligen?
topligen = ['FR1', 'IT1', 'ES1', 'GB1', 'L1']
ch_in_top = dict()
for jahr in range(1992,2017):
temp_liste = list()
for topliga in topligen:
try:
temp_liste.append(len(jahrbuch[str(jahr)][topliga]))
except:
temp_liste.append(0)
ch_in_top[jahr] = temp_liste
df_ch_in_top = pd.DataFrame.from_dict(ch_in_top, orient='index')
df_ch_in_top.columns = topligen
df_ch_in_top
fig, ax = plt.subplots(figsize=(14,8))
df_ch_in_top.sort_index(ascending=False).plot(kind='barh', stacked=True, ax=ax)
plt.title('Schweizer in den fünf Topligen')
plt.xlabel('')
plt.ylabel('')
plt.tight_layout()
plt.show()
fig.savefig('output/internationaleprojahr_topligen_horizontal.pdf')
fig.savefig('output/internationaleprojahr_topligen_horizontal.png')
fig.savefig('output/internationaleprojahr_topligen_horizontal.svg')
# ... und das Ganze noch als klassisches Säulendiagramm.
fig, ax = plt.subplots(figsize=(12,8))
df_ch_in_top.sort_index(ascending=True).plot(kind='bar', stacked=True, ax=ax)
plt.title('Schweizer in den fünf Topligen')
plt.xlabel('')
plt.ylabel('')
plt.tight_layout()
#plt.show()
fig.savefig('output/internationaleprojahr_topligen_vertikal.pdf')
fig.savefig('output/internationaleprojahr_topligen_vertikal.png')
fig.savefig('output/internationaleprojahr_topligen_vertikal.svg')
mpld3.save_html(fig, 'output/internationaleprojahr_topligen_vertikal.html')
# Prozentualer Anteil der in ausländischen Topligen tätigen Schweizer fürs Jahr 2016.
100 * df_ch_in_top.loc[2016] / df_ch_in_top.loc[2016].sum()
# Welche Spieler waren wann in einer der Topligen tätig?
topligen = ['FR1', 'IT1', 'ES1', 'GB1', 'L1']
df_jahrbuch = pd.DataFrame.from_dict(jahrbuch)
pd.set_option('display.max_colwidth', -1)
df_jahrbuch.ix[topligen].transpose()
# Körpergrösse: Wie gross sind die Schweizer Internationalen (alle ausländischen Ligen)?
df['Größe'] = df['Größe'].replace('', np.NaN).astype('float')
df['Größe'].describe()
# ... und als grafische Darstellung (Histogramm).
temp_min = df['Größe'].min()
temp_max = df['Größe'].max()
fig, ax = plt.subplots(figsize=(12,4))
df['Größe'].value_counts().sort_index().plot(kind='bar', color='darkred', ax=ax)
#plt.xticks(range(int(temp_min),int(temp_max)),range(int(temp_min),int(temp_max)))
plt.title('Wie gross sind die Schweizer Internationalen?')
plt.xlabel('Grösse in Metern')
plt.ylabel('Anzahl Spieler')
plt.tight_layout()
plt.show()
fig.savefig('output/grösse.pdf')
fig.savefig('output/grösse.png')
fig.savefig('output/grösse.svg')
mpld3.save_html(fig, 'output/grösse.html')
df[['Größe']].to_excel('output/grösse.xlsx')
# Wer sind die Kleinsten?
df[df['Größe'] < 1.74][['Größe', 'Position']].sort_values(by='Größe')
# Wer sind die Grössten?
df[df['Größe'] > 1.90][['Größe', 'Position']].sort_values(by='Größe', ascending=False)
# Auf welcher Position sollte man spielen, wenn man es in eine internationale Mannschaft schaffen will (alle Ligen)?
df['Position'].value_counts()
df[df['Position'] == 'Mittelfeld']['Geburtsort']
# ... und als Plot.
fig, ax = plt.subplots(figsize=(10,6))
df['Position'].value_counts().sort_values().plot(kind='barh', color='darkred', ax=ax)
plt.title('Auf welcher Position spielen die Schweizer Internationalen?')
plt.xlabel('Anzahl Spieler')
plt.ylabel('')
plt.tight_layout()
plt.show()
fig.savefig('output/position.pdf')
fig.savefig('output/position.png')
fig.savefig('output/position.svg')
mpld3.save_html(fig, 'output/position.html')
# Mit welchem Fuss sollte man spielen, wenn man es in ein internationales Team schaffen will (alle Ligen)?
df['Fuß'].value_counts()
# Welche Spielerberater betreuen besoners viele Schweizer Internationale?
df['Spielerberater'].value_counts().head(10)
# In welchem Ort wurden die meisten der Schweizer Internationalen geboren?
df['Geburtsort'].value_counts().head(30)
# Welche Schweizer Internationalen wurden in Bern geboren?
df[df['Geburtsort'] == 'Bern']
# Welche Schweizer Internationalen wurden im Kanton Bern geboren? (Die Personen werden anhand einer Liste mit sämtlichen
# Gemeindenamen gesucht. Aufgrund verschieder Schreibweisen ist diese Lösung aber nicht perfekt.)
kantonbern = ['Aarberg', 'Aarwangen', 'Adelboden', 'Aefligen', 'Aegerten', 'Aeschi bei Spiez', 'Aeschlen', 'Affoltern im Emmental', 'Albligen', 'Alchenstorf', 'Allmendingen', 'Amsoldingen', 'Arch', 'Arni (BE)', 'Attiswil', 'Auswil', 'Ballmoos', 'Bangerten', 'Bannwil', 'Bargen (BE)', 'Bäriswil', 'Bätterkinden', 'Beatenberg', 'Bellmund', 'Belp', 'Belpberg', 'Belprahon', 'Berken', 'Bern', 'Bettenhausen', 'Bévilard', 'Biel/Bienne', 'Biglen', 'Bleienbach', 'Bleiken bei Oberdiessbach', 'Blumenstein', 'Bolligen', 'Bollodingen', 'Boltigen', 'Bönigen', 'Bowil', 'Bremgarten bei Bern', 'Brenzikofen', 'Brienz (BE)', 'Brienzwiler', 'Brügg (BE)', 'Brüttelen', 'Buchholterberg', 'Büetigen', 'Bühl', 'Büren an der Aare', 'Büren zum Hof', 'Burgdorf', 'Burgistein', 'Busswil bei Büren', 'Busswil bei Melchnau', 'Champoz', 'Châtelat', 'Clavaleyres', 'Corcelles (BE)', 'Corgémont', 'Cormoret', 'Cortébert', 'Court', 'Courtelary', 'Crémines', 'Därligen', 'Därstetten', 'Deisswil bei', 'Münchenbuchsee', 'Diemerswil', 'Diemtigen mit Oey', 'Diessbach bei Büren', 'Diesse', 'Dotzigen', 'Dürrenroth', 'Eggiwil', 'Epsach', 'Eriswil', 'Eriz', 'Erlach', 'Erlenbach im Simmental', 'Ersigen', 'Eschert', 'Etzelkofen', 'Evilard', ' Fahrni', 'Farnern', 'Ferenbalm', 'Finsterhennen', 'Forst', 'Fraubrunnen', 'Frauenkappelen', 'Freimettigen', 'Frutigen ', 'Gadmen', 'Gals', 'Gampelen', 'Gelterfingen', 'Gerzensee', 'Golaten', 'Gondiswil', 'Graben', 'Grafenried', 'Grandval', 'Grindelwald', 'Grossaffoltern', 'Grosshöchstetten', 'Gsteig', 'Gsteigwiler', 'Guggisberg', 'Gündlischwand', 'Gurbrü', 'Gurzelen', 'Gutenburg', 'Guttannen', 'Habkern', 'Hagneck', 'Hasle bei Burgdorf', 'Hasliberg', 'Häutligen', 'Heiligenschwendi', 'Heimberg', 'Heimenhausen', 'Heimiswil', 'Hellsau', 'Herbligen', 'Hermiswil', 'Hermrigen', 'Herzogenbuchsee', 'Hilterfingen', 'Hindelbank', 'Höchstetten', 'Höfen bei Thun', 'Hofstetten bei Brienz', 'Homberg', 'Horrenbach-Buchen', 'Huttwil', 'Iffwil', 'Inkwil', 'Innertkirchen', 'Ins', 'Interlaken', 'Ipsach', 'Iseltwald', 'Ittigen', 'Jaberg', 'Jegenstorf', 'Jens', 'Kallnach', 'Kandergrund', 'Kandersteg', 'Kappelen', 'Kaufdorf', 'Kehrsatz', 'Kernenried', 'Kienersrüti', 'Kiesen', 'Kirchberg (BE)', 'Kirchdorf (BE)', 'Kirchenthurnen', 'Kirchlindach', 'Kleindietwil', 'Köniz', 'Konolfingen', 'Koppigen', 'Krattigen', 'Krauchthal', 'Kriechenwil', ' La Ferrière', 'La Heutte', 'La Neuveville', 'Lamboing', 'Landiswil', 'Längenbühl', 'Langenthal', 'Langnau im Emmental', 'Lauenen', 'Laupen', 'Lauperswil', 'Lauterbrunnen', 'Leimiswil', 'Leissigen', 'Lengnau (BE)', 'Lenk', 'Leuzigen', 'Ligerz', 'Limpach', 'Linden', 'Lohnstorf', 'Lotzwil', 'Loveresse', 'Lüscherz', 'Lütschental', 'Lützelflüh', 'Lyss', 'Lyssach', 'Madiswil', 'Malleray', 'Matten bei Interlaken', 'Mattstetten', 'Meienried', 'Meikirch', 'Meinisberg', 'Meiringen', 'Melchnau', 'Merzligen', 'Mirchel', 'Monible', 'Mont-Tramelan', 'Moosseedorf', 'Mörigen', 'Mötschwil', 'Moutier', 'Mühleberg', 'Mühledorf (BE)', 'Mühlethurnen', 'Mülchi', 'Münchenbuchsee', 'Münchenwiler', 'Münchringen', 'Münsingen', 'Müntschemier', 'Muri bei Bern', 'Neuenegg', 'Nidau', 'Niederbipp', 'Niederhünigen', 'Niedermuhlern', 'Niederönz', 'Niederösch', 'Niederried bei Interlaken', 'Niederried bei Kallnach', 'Niederstocken', 'Nods', 'Noflen', 'Oberbalm', 'Oberbipp', 'Oberburg', 'Oberdiessbach', 'Oberhofen am Thunersee', 'Oberhünigen', 'Oberlangenegg', 'Oberönz', 'Oberösch', 'Oberried am Brienzersee', 'Obersteckholz', 'Oberstocken', 'Oberthal', 'Oberwil bei Büren', 'Oberwil im Simmental', 'Ochlenberg', 'Oeschenbach', 'Oppligen', 'Orpund', 'Orvin', 'Ostermundigen Perrefitte', 'Péry', 'Pieterlen', 'Plagne', 'Pohlern', 'Pontenet', 'Port', 'Prêles', 'Radelfingen', 'Rapperswil (BE)', 'Rebévelier', 'Reconvilier', 'Reichenbach im Kandertal', 'Reisiswil', 'Renan (BE)', 'Reutigen', 'Riggisberg', 'Ringgenberg (BE)', 'Roches (BE)', 'Roggwil (BE)', 'Rohrbach', 'Rohrbachgraben', 'Romont (BE)', 'Röthenbach bei', 'Herzogenbuchsee', 'Röthenbach im Emmental', 'Rubigen', 'Rüderswil', 'Rüdtligen-Alchenflüh', 'Rüeggisberg', 'Rüegsau', 'Rumendingen', 'Rumisberg', 'Rümligen', 'Ruppoldsried', 'Rüschegg', 'Rüti bei Büren', 'Rüti bei Lyssach', 'Rüti bei Riggisberg', 'Rütschelen', 'Saanen', 'Safnern', 'Saicourt', 'Saint-Imier', 'Saules (BE)', 'Saxeten', 'Schalunen', 'Schangnau', 'Schattenhalb', 'Schelten', 'Scheunen', 'Scheuren', 'Schlosswil', 'Schüpfen', 'Schwadernau', 'Schwanden bei Brienz', 'Schwarzhäusern', 'Schwendibach', 'Seeberg', 'Seedorf (BE)', 'Seehof', 'Seftigen', 'Signau', 'Sigriswil', 'Siselen', 'Sonceboz-Sombeval', 'Sonvilier', 'Sornetan', 'Sorvilier', 'Souboz', 'Spiez', 'St. Stephan', 'Steffisburg', 'Stettlen', 'Studen', 'Sumiswald', 'Sutz-Lattrigen', '', ' Tägertschi', 'Täuffelen', 'Tavannes', 'Teuffenthal (BE)', 'Thierachern', 'Thörigen', 'Thun', 'Thunstetten', 'Toffen', 'Trachselwald', 'Tramelan', 'Treiten', 'Trimstein', 'Trub', 'Trubschachen', 'Tschugg', 'Tüscherz-Alfermée', 'Twann', 'Uebeschi', 'Uetendorf', 'Unterlangenegg', 'Unterseen', 'Untersteckholz', 'Ursenbach', 'Urtenen-Schönbühl', 'Uttigen', 'Utzenstorf', 'Vauffelin', 'Vechigen', 'Villeret', 'Vinelz', 'Wachseldorn', 'Wahlern', 'Wald (BE)', 'Walkringen', 'Walliswil bei Niederbipp', 'Walliswil bei Wangen', 'Walperswil', 'Walterswil (BE)', 'Wangen an der Aare', 'Wangenried', 'Wanzwil', 'Wattenwil', 'Wengi', 'Wichtrach', 'Wiedlisbach', 'Wiggiswil', 'Wilderswil', 'Wiler bei Utzenstorf', 'Wileroltigen', 'Willadingen', 'Wimmis', 'Wohlen bei Bern', 'Wolfisberg', 'Worb', 'Worben', 'Wynau', 'Wynigen', 'Wyssachen', 'Zauggenried', 'Zäziwil', 'Zielebach', 'Zollikofen', 'Zuzwil (BE)', 'Zweisimmen', 'Zwieselberg']
for gemeinde in kantonbern:
for index, row in df.iterrows():
if row['Geburtsort'] == gemeinde:
print(index, '(' + gemeinde + ')')
# Leider gibt es unerschiedliche Schreibweisen für die Ortschaften. Deshalb versuchen wir es mit einer unscharfen
# Suche. Achtung: Darin kann es etliche falsche Positive haben!
from fuzzywuzzy import fuzz
kantonbern = ['Aarberg', 'Aarwangen', 'Adelboden', 'Aefligen', 'Aegerten', 'Aeschi bei Spiez', 'Aeschlen', 'Affoltern im Emmental', 'Albligen', 'Alchenstorf', 'Allmendingen', 'Amsoldingen', 'Arch', 'Arni (BE)', 'Attiswil', 'Auswil', 'Ballmoos', 'Bangerten', 'Bannwil', 'Bargen (BE)', 'Bäriswil', 'Bätterkinden', 'Beatenberg', 'Bellmund', 'Belp', 'Belpberg', 'Belprahon', 'Berken', 'Bern', 'Bettenhausen', 'Bévilard', 'Biel/Bienne', 'Biglen', 'Bleienbach', 'Bleiken bei Oberdiessbach', 'Blumenstein', 'Bolligen', 'Bollodingen', 'Boltigen', 'Bönigen', 'Bowil', 'Bremgarten bei Bern', 'Brenzikofen', 'Brienz (BE)', 'Brienzwiler', 'Brügg (BE)', 'Brüttelen', 'Buchholterberg', 'Büetigen', 'Bühl', 'Büren an der Aare', 'Büren zum Hof', 'Burgdorf', 'Burgistein', 'Busswil bei Büren', 'Busswil bei Melchnau', 'Champoz', 'Châtelat', 'Clavaleyres', 'Corcelles (BE)', 'Corgémont', 'Cormoret', 'Cortébert', 'Court', 'Courtelary', 'Crémines', 'Därligen', 'Därstetten', 'Deisswil bei', 'Münchenbuchsee', 'Diemerswil', 'Diemtigen mit Oey', 'Diessbach bei Büren', 'Diesse', 'Dotzigen', 'Dürrenroth', 'Eggiwil', 'Epsach', 'Eriswil', 'Eriz', 'Erlach', 'Erlenbach im Simmental', 'Ersigen', 'Eschert', 'Etzelkofen', 'Evilard', ' Fahrni', 'Farnern', 'Ferenbalm', 'Finsterhennen', 'Forst', 'Fraubrunnen', 'Frauenkappelen', 'Freimettigen', 'Frutigen ', 'Gadmen', 'Gals', 'Gampelen', 'Gelterfingen', 'Gerzensee', 'Golaten', 'Gondiswil', 'Graben', 'Grafenried', 'Grandval', 'Grindelwald', 'Grossaffoltern', 'Grosshöchstetten', 'Gsteig', 'Gsteigwiler', 'Guggisberg', 'Gündlischwand', 'Gurbrü', 'Gurzelen', 'Gutenburg', 'Guttannen', 'Habkern', 'Hagneck', 'Hasle bei Burgdorf', 'Hasliberg', 'Häutligen', 'Heiligenschwendi', 'Heimberg', 'Heimenhausen', 'Heimiswil', 'Hellsau', 'Herbligen', 'Hermiswil', 'Hermrigen', 'Herzogenbuchsee', 'Hilterfingen', 'Hindelbank', 'Höchstetten', 'Höfen bei Thun', 'Hofstetten bei Brienz', 'Homberg', 'Horrenbach-Buchen', 'Huttwil', 'Iffwil', 'Inkwil', 'Innertkirchen', 'Ins', 'Interlaken', 'Ipsach', 'Iseltwald', 'Ittigen', 'Jaberg', 'Jegenstorf', 'Jens', 'Kallnach', 'Kandergrund', 'Kandersteg', 'Kappelen', 'Kaufdorf', 'Kehrsatz', 'Kernenried', 'Kienersrüti', 'Kiesen', 'Kirchberg (BE)', 'Kirchdorf (BE)', 'Kirchenthurnen', 'Kirchlindach', 'Kleindietwil', 'Köniz', 'Konolfingen', 'Koppigen', 'Krattigen', 'Krauchthal', 'Kriechenwil', ' La Ferrière', 'La Heutte', 'La Neuveville', 'Lamboing', 'Landiswil', 'Längenbühl', 'Langenthal', 'Langnau im Emmental', 'Lauenen', 'Laupen', 'Lauperswil', 'Lauterbrunnen', 'Leimiswil', 'Leissigen', 'Lengnau (BE)', 'Lenk', 'Leuzigen', 'Ligerz', 'Limpach', 'Linden', 'Lohnstorf', 'Lotzwil', 'Loveresse', 'Lüscherz', 'Lütschental', 'Lützelflüh', 'Lyss', 'Lyssach', 'Madiswil', 'Malleray', 'Matten bei Interlaken', 'Mattstetten', 'Meienried', 'Meikirch', 'Meinisberg', 'Meiringen', 'Melchnau', 'Merzligen', 'Mirchel', 'Monible', 'Mont-Tramelan', 'Moosseedorf', 'Mörigen', 'Mötschwil', 'Moutier', 'Mühleberg', 'Mühledorf (BE)', 'Mühlethurnen', 'Mülchi', 'Münchenbuchsee', 'Münchenwiler', 'Münchringen', 'Münsingen', 'Müntschemier', 'Muri bei Bern', 'Neuenegg', 'Nidau', 'Niederbipp', 'Niederhünigen', 'Niedermuhlern', 'Niederönz', 'Niederösch', 'Niederried bei Interlaken', 'Niederried bei Kallnach', 'Niederstocken', 'Nods', 'Noflen', 'Oberbalm', 'Oberbipp', 'Oberburg', 'Oberdiessbach', 'Oberhofen am Thunersee', 'Oberhünigen', 'Oberlangenegg', 'Oberönz', 'Oberösch', 'Oberried am Brienzersee', 'Obersteckholz', 'Oberstocken', 'Oberthal', 'Oberwil bei Büren', 'Oberwil im Simmental', 'Ochlenberg', 'Oeschenbach', 'Oppligen', 'Orpund', 'Orvin', 'Ostermundigen Perrefitte', 'Péry', 'Pieterlen', 'Plagne', 'Pohlern', 'Pontenet', 'Port', 'Prêles', 'Radelfingen', 'Rapperswil (BE)', 'Rebévelier', 'Reconvilier', 'Reichenbach im Kandertal', 'Reisiswil', 'Renan (BE)', 'Reutigen', 'Riggisberg', 'Ringgenberg (BE)', 'Roches (BE)', 'Roggwil (BE)', 'Rohrbach', 'Rohrbachgraben', 'Romont (BE)', 'Röthenbach bei', 'Herzogenbuchsee', 'Röthenbach im Emmental', 'Rubigen', 'Rüderswil', 'Rüdtligen-Alchenflüh', 'Rüeggisberg', 'Rüegsau', 'Rumendingen', 'Rumisberg', 'Rümligen', 'Ruppoldsried', 'Rüschegg', 'Rüti bei Büren', 'Rüti bei Lyssach', 'Rüti bei Riggisberg', 'Rütschelen', 'Saanen', 'Safnern', 'Saicourt', 'Saint-Imier', 'Saules (BE)', 'Saxeten', 'Schalunen', 'Schangnau', 'Schattenhalb', 'Schelten', 'Scheunen', 'Scheuren', 'Schlosswil', 'Schüpfen', 'Schwadernau', 'Schwanden bei Brienz', 'Schwarzhäusern', 'Schwendibach', 'Seeberg', 'Seedorf (BE)', 'Seehof', 'Seftigen', 'Signau', 'Sigriswil', 'Siselen', 'Sonceboz-Sombeval', 'Sonvilier', 'Sornetan', 'Sorvilier', 'Souboz', 'Spiez', 'St. Stephan', 'Steffisburg', 'Stettlen', 'Studen', 'Sumiswald', 'Sutz-Lattrigen', '', ' Tägertschi', 'Täuffelen', 'Tavannes', 'Teuffenthal (BE)', 'Thierachern', 'Thörigen', 'Thun', 'Thunstetten', 'Toffen', 'Trachselwald', 'Tramelan', 'Treiten', 'Trimstein', 'Trub', 'Trubschachen', 'Tschugg', 'Tüscherz-Alfermée', 'Twann', 'Uebeschi', 'Uetendorf', 'Unterlangenegg', 'Unterseen', 'Untersteckholz', 'Ursenbach', 'Urtenen-Schönbühl', 'Uttigen', 'Utzenstorf', 'Vauffelin', 'Vechigen', 'Villeret', 'Vinelz', 'Wachseldorn', 'Wahlern', 'Wald (BE)', 'Walkringen', 'Walliswil bei Niederbipp', 'Walliswil bei Wangen', 'Walperswil', 'Walterswil (BE)', 'Wangen an der Aare', 'Wangenried', 'Wanzwil', 'Wattenwil', 'Wengi', 'Wichtrach', 'Wiedlisbach', 'Wiggiswil', 'Wilderswil', 'Wiler bei Utzenstorf', 'Wileroltigen', 'Willadingen', 'Wimmis', 'Wohlen bei Bern', 'Wolfisberg', 'Worb', 'Worben', 'Wynau', 'Wynigen', 'Wyssachen', 'Zauggenried', 'Zäziwil', 'Zielebach', 'Zollikofen', 'Zuzwil (BE)', 'Zweisimmen', 'Zwieselberg']
for gemeinde in kantonbern:
for index, row in df.iterrows():
try:
test = fuzz.partial_ratio(row['Geburtsort'], gemeinde)
if test == 100:
print('Ev.', index, '(' + row['Geburtsort'] + ')')
except:
pass
# Mit welchem Schuhmodell hat man die besten Chancen?
def nichtsalseinschuh(schuh):
try:
schuh = re.match(r'(.*)\n.', schuh)
return schuh.group(1)
except:
return ''
df['Schuhmodell_neu'] = df['Schuhmodell'].apply(nichtsalseinschuh)
df['Schuhmodell_neu'].value_counts().head(9)
# Funktion zum Umformatieren und Umrechnen der Wertangaben in Zahlen.
def mirweinümmerli(wert):
try:
wert = wert.replace(',', '')
if 'Mio.' in wert:
temp_wert = re.match(r'(\d.*) Mio.', wert)
wert = temp_wert.group(1) + '0000'
elif 'Tsd.' in wert:
temp_wert = re.match(r'(\d.*) Tsd.', wert)
wert = temp_wert.group(1) + '000'
elif 'ablösefrei' in wert:
wert = 0
elif '?' in wert:
wert = np.NaN
return float(wert)
except:
return wert
# Suche nach dem ersten Transfer von der Schweiz ins Ausland.
def funk_jugendmannschaft(team):
jugendmannschaften = ['U12', 'U13', 'U14', 'U15', 'U16', 'U17', 'U18', 'U19', 'U20', 'U21', 'U22', 'U23', 'U24', 'Jugend', 'Jgd.']
for u_mannschaft in jugendmannschaften:
if u_mannschaft in team:
return True
else:
pass
def ersterauslandtransfer(row, transfernummer):
for transfer in transfernummer:
temp_schalter = False
try:
temp_list = ast.literal_eval(row[transfer])
templand1 = temp_list[3]
templand2 = temp_list[5]
tempteam2 = temp_list[4]
temp_schalter = funk_jugendmannschaft(tempteam2)
if temp_schalter == True:
pass
else:
if templand1 == 'Schweiz' and templand2 != 'Schweiz':
if tempteam2 == 'Vereinslos':
pass
elif tempteam2 == 'Karriereende':
pass
else:
temp_list.append(transfer)
return temp_list
else:
pass
except:
pass
itransfer = dict()
for spieler in df.index:
itransfer[spieler] = ersterauslandtransfer(df.ix[spieler], transfernummer)
transfer_infos = ['Saison', 'Datum', 'Von Klub', 'Von Land', 'Zu Klub', 'Zu Land', 'Wert', 'Ablösesumme', 'Transfer', 'Geburtsdatum']
df_gointernational = pd.DataFrame(itransfer).transpose()
df_gointernational = df_gointernational.merge(df[['Geburtsdatum']], left_index=True, right_index=True)
df_gointernational.columns = transfer_infos
df_gointernational['Geburtsdatum'] = pd.to_datetime(df_gointernational['Geburtsdatum'], format='%d.%m.%Y')
df_gointernational['Datum'] = pd.to_datetime(df_gointernational['Datum'], format='%d.%m.%Y')
df_gointernational['Alter'] = (df_gointernational['Datum'] - df_gointernational['Geburtsdatum']).astype('timedelta64[Y]')
df_gointernational['Wert'] = df_gointernational['Wert'].apply(mirweinümmerli)
df_gointernational['Wert'] = df_gointernational['Wert'].replace('-',np.NaN)
df_gointernational['Wert'] = df_gointernational['Wert'].astype(float)
df_gointernational['Ablösesumme'] = df_gointernational['Ablösesumme'].apply(mirweinümmerli)
df_gointernational = df_gointernational[df_gointernational.Datum.notnull()] # Leereinträge werden herausgefiltert.
df_gointernational.to_excel('output/gointernational.xlsx')
df_gointernational.to_csv('output/gointernational.csv')
df_gointernational.head()
df_gointernational[df_gointernational['Von Klub'] == 'BSC Young Boys']
df.loc['Christian Schwegler']
df_gointernational['Alter'].describe()
# Wie alt ist der mittlere Spieler beim Wechsel (Median)?
df_gointernational['Alter'].median()
temp_min = df_gointernational['Alter'].min()
temp_max = df_gointernational['Alter'].max()
fig, ax = plt.subplots(figsize=(14,8))
df_gointernational['Alter'].hist(bins=int(temp_max-temp_min), color='darkred')
plt.title('Alter beim Wechsel ins Ausland')
plt.xlabel('')
plt.ylabel('Anzahl Fussballer')
plt.xticks(range(int(temp_min),int(temp_max)),range(int(temp_min),int(temp_max)))
plt.tight_layout()
plt.show()
fig.savefig('output/alterbeimwechsel.pdf')
fig.savefig('output/alterbeimwechsel.png')
fig.savefig('output/alterbeimwechsel.svg')
mpld3.save_html(fig, 'output/alterbeimwechsel.html')
df_gointernational[['Alter']].to_excel('output/alterbeimwechsel.xlsx')
# Welche Fussballer wechselten in jungen Jahren aufs internationale Parkett?
df_gointernational['Alter'].sort_values().astype('int').head(10)
# Welche Fussballer waren beim Wechsel ins Ausland besonders alt?
# Achtung, berücksichtigt wird der erste Wechsel von der Schweiz ins Ausland. Einige dieser Spieler hier haben aber
# zuerst aus dem Ausland in die Schweiz gewechselt, bevor sie wieder ins Ausland zogen. Sie sind aber Schweizer Bürger.
# Diese Spieler haben natürlich auch Einfluss auf den Mittelwert.
df_gointernational['Alter'].sort_values(ascending=False).astype('int').head(10)
# Schauen wir uns die Transfers von Nestor Subiat an.
print("Nestor Subiat")
for i in range(1,12):
print(df.loc['Nestor Subiat']['Transfer_' + str(i)])
# Wie hoch ist der Marktwert beim Wechsel ins Ausland?
fig, ax = plt.subplots(figsize=(5,10))
df_gointernational[['Wert']].dropna().sort_values(by='Wert', ascending=True).tail(20).plot(kind='barh', color='darkred', ax=ax)
plt.title('Wert beim ersten Wechsel ins Ausland')
plt.xlabel('in Mio. Euro')
plt.ylabel('')
plt.tight_layout()
plt.show()
fig.savefig('output/wertbeimwechsel.pdf')
fig.savefig('output/wertbeimwechsel.png')
fig.savefig('output/wertbeimwechsel.svg')
mpld3.save_html(fig, 'output/wertbeimwechsel.html')
# Wie hängen das Alter beim ersten Auslandtransfer und der Wert zu diesem Zeitpunkt zusammen?
df_gointernational[['Wert','Alter']].dropna().plot(kind='scatter', x='Alter', y='Wert', figsize=[15,7])
# Wer wechselte bei hohem geschätzten Wert?
pd.DataFrame(df_gointernational['Wert'].sort_values(ascending=False).head(20))
# Wer wechselte bei tiefem (geschätztem) Wert?
pd.DataFrame(df_gointernational['Wert'].sort_values().head(20))
# Für wen wurden besonders hohe Ablösesummen bezahlt?
pd.to_numeric(df_gointernational['Ablösesumme'], errors='coerce').sort_values(ascending=False).head(13)
# Beim wie vielten "Anlauf" wechseln die Spieler normalerweise ins Ausland?
df_gointernational['Transfer'].value_counts()
df_gointernational['Transfer'].value_counts().sort_values().plot(kind='barh')
df_gointernational[df_gointernational['Transfer'] == 'Transfer_12']
# Entwicklung Marktwert im Ausland.
marktwert_dict = dict()
for temp_spieler in df_gointernational.index:
temp_liste = list()
try:
temp_row = df.loc[temp_spieler]
for transfer in transfernummer:
temp_liste.append(mirweinümmerli(ast.literal_eval(temp_row[transfer])[6]))
except:
pass
marktwert_dict[temp_spieler] = temp_liste
df_marktwert = pd.DataFrame.from_dict(marktwert_dict, orient='index')
df_marktwert.columns = transfernummer
df_marktwert.to_csv('output/marktwert.csv')
df_marktwert.head()
wert_international_dict = dict()
for spieler in df_gointernational.index:
temp_spieler_liste = df.loc[spieler][df.columns[df.columns.to_series().str.contains('Transfer_')]].tolist()
temp_transfer = int(df_gointernational.loc[spieler]['Transfer'].replace('Transfer_', ''))
temp_liste = list()
for transfer in range(len(temp_spieler_liste)):
try:
temp_wert = (ast.literal_eval(temp_spieler_liste[transfer])[6])
if temp_wert == '-':
temp_wert.replace('-', np.NaN)
temp_wert = mirweinümmerli(temp_wert)
except:
temp_wert = np.NaN
temp_liste.append(temp_wert)
temp_liste = temp_liste[temp_transfer - 1:]
wert_international_dict[spieler] = temp_liste
df_wert_international = pd.DataFrame.from_dict(wert_international_dict, orient='index')
df_wert_international.to_excel('output/wert_international.xlsx')
df_wert_international.to_csv('output/wert_international.csv')
df_wert_international.head()
# Wie entwickelte sich der Marktwert der Spieler im Ausland?
fig, ax = plt.subplots(figsize=(14,8))
df_wert_international.transpose().plot(ax=ax)
plt.title('Entwicklung des Marktwerts pro Transfer')
plt.xlabel('')
#plt.ylabel('Anzahl Fussballer')
plt.xticks(range(0,len(transfernummer)))
plt.tight_layout()
plt.show()
# Wie entwickelte sich der Marktwert ausgewählter Spieler im Ausland?
selektion = ['Innocent Emeghara', 'Gelson Fernandes', 'Carlo Polli', 'Mobulu M\'Futi']
df_wert_international_selektion = df_wert_international
df_wert_international_selektion = df_wert_international_selektion[df_wert_international_selektion.index.isin(selektion)]
fig, ax = plt.subplots(figsize=(12,6))
df_wert_international_selektion.transpose().plot(ax=ax)
plt.title('Entwicklung des Marktwerts im Ausland')
plt.xlabel('')
#plt.ylabel('Anzahl Fussballer')
plt.xticks(range(0,len(transfernummer)))
plt.tight_layout()
plt.show()
fig.savefig('output/wertinternational_selektion.pdf')
fig.savefig('output/wertinternational_selektion.png')
fig.savefig('output/wertinternational_selektion.svg')
mpld3.save_html(fig, 'output/wertinternational_selektion.html')
# Wohin wechselten die Berner Spieler?
bernerspieler = ['Alain Sutter', 'François Affolter', 'Rémo Meyer', 'Florent Hadergjonaj', 'Michael Frey', 'Roman Bürki']
df_gointernational[df_gointernational.index.isin(bernerspieler)]
# Wohin welchselten die YB-Spieler?
df_gointernational[df_gointernational['Von Klub'] == 'BSC Young Boys']
# Wo wohnen die Kandidaten (siehe interaktive Karte map_kandaten.html).
df_yb_ins_ausland = df_gointernational[df_gointernational['Von Klub'] == 'BSC Young Boys']
df_thun_ins_ausland = df_gointernational[df_gointernational['Von Klub'] == 'FC Thun']
df_biel_ins_ausland = df_gointernational[df_gointernational['Von Klub'] == 'FC Biel-Bienne']
df_be_ins_ausland = pd.concat([df_yb_ins_ausland, df_thun_ins_ausland, df_biel_ins_ausland])
df_be_ins_ausland = df_be_ins_ausland[['Datum', 'Von Klub', 'Zu Klub', 'Zu Land', 'Wert', 'Alter']]
df_be_ins_ausland['Alter'] = df_be_ins_ausland['Alter'].astype(int)
df_be_ins_ausland['Wert'] = df_be_ins_ausland['Wert'] / 1000000
def datumsrechner(datum):
return datum.strftime('%d. %B %Y')
locale.setlocale(locale.LC_ALL, 'de_CH.utf8')
df_be_ins_ausland['Datum'] = df_be_ins_ausland['Datum'].apply(datumsrechner)
df_be_ins_ausland
# Die Koordinaten der Stadien werden manuell hinzugefügt.
df_be_ins_ausland.loc['Florent Hadergjonaj', 'lat'] = 48.76337
df_be_ins_ausland.loc['Florent Hadergjonaj', 'lon'] = 11.42422
df_be_ins_ausland.loc['Alain Rochat', 'lat'] = 48.09805
df_be_ins_ausland.loc['Alain Rochat', 'lon'] = -1.72008
df_be_ins_ausland.loc['Davide Chiumiento', 'lat'] = 45.10978
df_be_ins_ausland.loc['Davide Chiumiento', 'lon'] = 7.64198
df_be_ins_ausland.loc['Michael Frey', 'lat'] = 50.61687
df_be_ins_ausland.loc['Michael Frey', 'lon'] = 3.07121
df_be_ins_ausland.loc['François Affolter', 'lat'] = 53.06642
df_be_ins_ausland.loc['François Affolter', 'lon'] = 8.83788
df_be_ins_ausland.loc['Johan Vonlanthen', 'lat'] = 51.44158
df_be_ins_ausland.loc['Johan Vonlanthen', 'lon'] = 5.46790
df_be_ins_ausland.loc['Mauro Lustrinelli', 'lat'] = 50.09991
df_be_ins_ausland.loc['Mauro Lustrinelli', 'lon'] = 14.41589
df_be_ins_ausland.loc['Timm Klose', 'lat'] = 49.42622
df_be_ins_ausland.loc['Timm Klose', 'lon'] = 11.12560
df_be_ins_ausland.loc['David Pallas', 'lat'] = 51.49006
df_be_ins_ausland.loc['David Pallas', 'lon'] = 7.23644
df_be_ins_ausland.loc['Fabian Stoller', 'lat'] = 32.1042324
df_be_ins_ausland.loc['Fabian Stoller', 'lon'] = 34.8655205
df_be_ins_ausland.loc['Sokol Maliqi', 'lat'] = 34.9353264
df_be_ins_ausland.loc['Sokol Maliqi', 'lon'] = 32.97413
df_be_ins_ausland.loc['Johan Vonlanthen', 'Wert'] = '-'
# Die Karte wird generiert.
map_be = folium.Map(location=[46.9492,7.4428], zoom_start=4, tiles='Stamen Toner')
for spieler in df_be_ins_ausland.index:
koordinaten = df_be_ins_ausland.loc[spieler]['lat'],df_be_ins_ausland.loc[spieler]['lon']
html = spieler + ' wechselte am ' + str(df_be_ins_ausland.loc[spieler]['Datum']) + ' im Alter von ' + str(df_be_ins_ausland.loc[spieler]['Alter']) + ' Jahren von ' + df_be_ins_ausland.loc[spieler]['Von Klub'] + ' zu ' + df_be_ins_ausland.loc[spieler]['Zu Klub'] + ' in ' + df_be_ins_ausland.loc[spieler]['Zu Land'] + '. '
if df_be_ins_ausland.loc[spieler]['Wert'] == '-':
pass
else:
html = html + 'Sein damaliger Marktwert wurde auf ' + str(df_be_ins_ausland.loc[spieler]['Wert']) + ' Millionen Euro geschätzt.'
popup = folium.Popup(html, max_width=200)
folium.Marker(koordinaten, icon=folium.Icon(color='darkred',icon='info-sign'), popup=popup).add_to(map_be)
map_be.save('output/map_be.html')
map_be
fig, ax = plt.subplots(figsize=(6,6))
df_gointernational['Von Klub'].value_counts().sort_values(ascending=True).tail(14).plot(kind='barh', color='darkred', ax=ax)
plt.title('Grasshoppers ist der grösste Exporteur')
plt.xlabel('Anzahl Internationale')
#plt.ylabel('Anzahl Fussballer')
plt.tight_layout()
plt.show()
fig.savefig('output/export_klubs.pdf')
fig.savefig('output/export_klubs.png')
fig.savefig('output/export_klubs.svg')
mpld3.save_html(fig, 'output/export_klubs.html')
df_yb_ins_ausland.loc['Michael Frey', 'lat'] = '765'
df_yb_ins_ausland.loc['François Affolter', 'lat'] = '765'
df_yb_ins_ausland.loc['Johan Vonlanthen', 'lat'] = '765'
df_yb_ins_ausland
df_yb_ins_ausland
# Welches sind die populärsten Länder für den ersten Wechsel?
df_gointernational['Zu Land'].value_counts()
df_gointernational['Zu Land'].value_counts().sort_values(ascending=True).tail(9).plot(kind='barh')
# Welches sind die beliebtesten Vereine beim ersten Wechsel aufs internationale Parkett?
df_gointernational['Zu Klub'].value_counts()
df_gointernational['Zu Klub'].value_counts().sort_values(ascending=True).tail(13).plot(kind='barh')
# To do: Export der Stationen von ausgewählten Spielern. Inklusive Geocoding.
df_mapdaten = df[['Transfer_1','Transfer_2','Transfer_3','Transfer_4','Transfer_5','Transfer_6','Transfer_7','Transfer_8','Transfer_9','Transfer_10','Transfer_11','Transfer_12','Transfer_13','Transfer_14','Transfer_15','Transfer_16','Transfer_17','Transfer_18','Transfer_19','Transfer_20','Transfer_21']]
df_mapdaten.to_csv('output/mapdaten.csv')
transfer_infos = ['Saison', 'Datum', 'Von Klub', 'Von Land', 'Zu Klub', 'Zu Land', 'Wert', 'Ablösesumme', 'Transfer', 'Geburtsdatum']
df_mapdaten = pd.DataFrame(itransfer).transpose()
# Welche Fussballspieler bringen entsprechen am besten dem "perfekten Fussballer"?
df[(df['Geburtsort'] == 'Zürich') &
(df['Position'] == 'Abwehr - Innenverteidiger')][['Geburtsort', 'Position']]
# Welche Fussballspieler bringen entsprechen am besten dem "perfekten Fussballer"?
df[(df['Geburtsort'] == 'Zürich') &
(df['Größe'] == 1.83)][['Geburtsort', 'Größe']]
# Welche Fussballspieler bringen entsprechen am besten dem "perfekten Fussballer"?
df[(df['Position'] == 'Abwehr - Innenverteidiger') &
(df['Größe'] == 1.83)][['Position', 'Größe']]
# Welche Fussballspieler bringen entsprechen am besten dem "perfekten Fussballer"?
df[(df['Position'] == 'Abwehr - Innenverteidiger') &
(df['Größe'] >= 1.81) &
(df['Größe'] <= 1.85)][['Position', 'Größe', 'Geburtsort']]