import pandas as pd
import numpy as np
Exploratory Data Analysis af adgangsgrundlag for videregående uddannelser
Data hentet fra UFM - Link
= pd.read_excel("data/day21/Ansøgere_adgangsgrundlag.xlsx") df
/Users/jonskogland/Documents/hjemmeside - Jon Skogland/lokopu.github.io/venv/lib/python3.13/site-packages/openpyxl/styles/stylesheet.py:237: UserWarning: Workbook contains no default style, apply openpyxl's default
warn("Workbook contains no default style, apply openpyxl's default")
df
Den Koordinerede Tilmelding | Unnamed: 1 | Unnamed: 2 | 1. prioritets-ansøgere fordelt på adgangsgrundlag | Unnamed: 4 | Unnamed: 5 | Unnamed: 6 | Unnamed: 7 | Unnamed: 8 | Unnamed: 9 | ... | Unnamed: 11 | Unnamed: 12 | Unnamed: 13 | Unnamed: 14 | Unnamed: 15 | Unnamed: 16 | Unnamed: 17 | Unnamed: 18 | Unnamed: 19 | Unnamed: 20 | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0 | NaN | NaN | NaN | 22-juli-2024 | NaN | NaN | NaN | NaN | NaN | NaN | ... | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN |
1 | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | ... | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN |
2 | NaN | NaN | NaN | 1=stx | NaN | NaN | NaN | NaN | NaN | NaN | ... | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN |
3 | NaN | NaN | NaN | 2=hf | NaN | NaN | NaN | NaN | NaN | NaN | ... | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN |
4 | NaN | NaN | NaN | 3=hhx | NaN | NaN | NaN | NaN | NaN | NaN | ... | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN |
... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... |
944 | 8800 | Erhvervsakademi Dania | 84410 | Produktionsteknolog, Randers SØ, Studiestart: ... | 6 | NaN | 1.0 | 1.0 | NaN | 1.0 | ... | NaN | NaN | 1.0 | NaN | NaN | NaN | 1.0 | NaN | NaN | NaN |
945 | 8800 | Erhvervsakademi Dania | 86160 | Service- og oplevelsesøkonom, Randers SØ, Stud... | 15 | 1 | 7.0 | 1.0 | 3.0 | NaN | ... | NaN | NaN | 1.0 | 1.0 | NaN | NaN | NaN | 1.0 | NaN | NaN |
946 | 8800 | Erhvervsakademi Dania | 86164 | Service- og oplevelsesøkonom, Randers SØ, E-læ... | 45 | NaN | 12.0 | 10.0 | 3.0 | 4.0 | ... | NaN | NaN | 5.0 | 7.0 | NaN | 1.0 | NaN | 1.0 | 1.0 | 1.0 |
947 | 8800 | Erhvervsakademi Dania | 86166 | Service- og oplevelsesøkonom, Randers SØ, E-læ... | 9 | NaN | 1.0 | 3.0 | 4.0 | NaN | ... | NaN | NaN | 1.0 | NaN | NaN | NaN | NaN | NaN | NaN | NaN |
948 | 8800 | Erhvervsakademi Dania | 87110 | Logistikøkonom , Hobro, Studiestart: sommerstart | 15 | NaN | 4.0 | 5.0 | 4.0 | 1.0 | ... | NaN | NaN | NaN | NaN | NaN | 1.0 | NaN | NaN | NaN | NaN |
949 rows × 21 columns
Her ses det at dataframe’en har nogle header rækker øverst som skal filtreres fra, samtidigt er der data som skal bruges til at indsætte navne på adgangsgrundlagene for kolonnerne fra 4 og frem. da der ellers kun står et tal som er svært at læse.
= df.head(17) adgange
= adgange.iloc[2:,3] adgange
= adgange.str.split("=", expand=True) adgange
= adgange.rename(columns={0: "id", 1: "adgangsgrundlag"}) adgange
adgange
id | adgangsgrundlag | |
---|---|---|
2 | 1 | stx |
3 | 2 | hf |
4 | 3 | hhx |
5 | 4 | htx |
6 | 5 | International Baccalaureate (IB) |
7 | 6 | GIF |
8 | 7 | Adgangseksamen for ingeniøruddannelser |
9 | 8 | Erhvervsuddannelse (EUD) |
10 | 9 | Andet adgangsgrundlag |
11 | 10 | International Baccalaureate (IB) fra udlandet |
12 | 11 | Anden adgangsgivende eksamen fra ud-landet |
13 | 12 | eux |
14 | 13 | eux 1. del |
15 | 14 | Færøsk gymnasial eksamen |
16 | 15 | Grønlandsk gymnasial eksamen |
= df.iloc[18:] df
= df.iloc[0]
new_header = df[1:]
df = new_header df.columns
Så er hoveddataene fra excelarket korrekt afgrænset og det har fået de korrekte kolonner
df
18 | InstNr | InstNavn | OptNr | OptNavn | I alt | Uoplyst | 1.0 | 2.0 | 3.0 | 4.0 | ... | 6.0 | 7.0 | 8.0 | 9.0 | 10.0 | 11.0 | 12.0 | 13.0 | 14.0 | 15.0 |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
19 | 1000 | Københavns Universitet | 10110 | Medicin, København Ø, Studiestart: sommer- og ... | 1687 | 4 | 1107.0 | 111.0 | 14.0 | 116.0 | ... | 11.0 | NaN | 1.0 | 10.0 | 11.0 | 240.0 | 1.0 | 2.0 | 13.0 | 1.0 |
20 | 1000 | Københavns Universitet | 10112 | Medicin, Køge, Studiestart: sommer- og vinters... | 234 | NaN | 147.0 | 25.0 | 1.0 | 38.0 | ... | NaN | NaN | 2.0 | 3.0 | 1.0 | 10.0 | NaN | NaN | NaN | NaN |
21 | 1000 | Københavns Universitet | 10115 | Folkesundhedsvidenskab, København K, Studiesta... | 88 | NaN | 81.0 | 3.0 | NaN | 1.0 | ... | NaN | NaN | NaN | NaN | NaN | 2.0 | NaN | NaN | NaN | 1.0 |
22 | 1000 | Københavns Universitet | 10117 | Farmaci, København Ø, Studiestart: sommerstart | 291 | NaN | 194.0 | 32.0 | 2.0 | 44.0 | ... | 7.0 | NaN | NaN | 3.0 | NaN | 4.0 | NaN | NaN | 3.0 | NaN |
23 | 1000 | Københavns Universitet | 10120 | Odontologi, København Ø, Studiestart: sommerstart | 471 | 1 | 310.0 | 46.0 | 8.0 | 54.0 | ... | 8.0 | NaN | 1.0 | 5.0 | NaN | 27.0 | NaN | NaN | 7.0 | NaN |
... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... |
944 | 8800 | Erhvervsakademi Dania | 84410 | Produktionsteknolog, Randers SØ, Studiestart: ... | 6 | NaN | 1.0 | 1.0 | NaN | 1.0 | ... | NaN | NaN | 1.0 | NaN | NaN | NaN | 1.0 | NaN | NaN | NaN |
945 | 8800 | Erhvervsakademi Dania | 86160 | Service- og oplevelsesøkonom, Randers SØ, Stud... | 15 | 1 | 7.0 | 1.0 | 3.0 | NaN | ... | NaN | NaN | 1.0 | 1.0 | NaN | NaN | NaN | 1.0 | NaN | NaN |
946 | 8800 | Erhvervsakademi Dania | 86164 | Service- og oplevelsesøkonom, Randers SØ, E-læ... | 45 | NaN | 12.0 | 10.0 | 3.0 | 4.0 | ... | NaN | NaN | 5.0 | 7.0 | NaN | 1.0 | NaN | 1.0 | 1.0 | 1.0 |
947 | 8800 | Erhvervsakademi Dania | 86166 | Service- og oplevelsesøkonom, Randers SØ, E-læ... | 9 | NaN | 1.0 | 3.0 | 4.0 | NaN | ... | NaN | NaN | 1.0 | NaN | NaN | NaN | NaN | NaN | NaN | NaN |
948 | 8800 | Erhvervsakademi Dania | 87110 | Logistikøkonom , Hobro, Studiestart: sommerstart | 15 | NaN | 4.0 | 5.0 | 4.0 | 1.0 | ... | NaN | NaN | NaN | NaN | NaN | 1.0 | NaN | NaN | NaN | NaN |
930 rows × 21 columns
Ovenstående dataframe er dog i wide format og det vil derfor være besværligt at lave analyse på. Derfor skal kolonnerne 1-15 pivoteres sådan at vi får to kolonner i stedet: “adgangsrundlag”, hvor værdierne vil være teksten på den uddannelse de studerende kommer fra, og “ansøgere” som vil være det antal som har søgt uddannelsen fra det givne adgangsgrundlag - denne vil erstatte “i alt” kolonnen da denne kan summeres efterfølgende.
= df.columns.tolist() res
res
['InstNr',
'InstNavn',
'OptNr',
'OptNavn',
'I alt',
'Uoplyst',
np.float64(1.0),
np.float64(2.0),
np.float64(3.0),
np.float64(4.0),
np.float64(5.0),
np.float64(6.0),
np.float64(7.0),
np.float64(8.0),
np.float64(9.0),
np.float64(10.0),
np.float64(11.0),
np.float64(12.0),
np.float64(13.0),
np.float64(14.0),
np.float64(15.0)]
= res[0:5] res
= pd.melt(df, id_vars=res) melted
melted
InstNr | InstNavn | OptNr | OptNavn | I alt | 18 | value | |
---|---|---|---|---|---|---|---|
0 | 1000 | Københavns Universitet | 10110 | Medicin, København Ø, Studiestart: sommer- og ... | 1687 | Uoplyst | 4 |
1 | 1000 | Københavns Universitet | 10112 | Medicin, Køge, Studiestart: sommer- og vinters... | 234 | Uoplyst | NaN |
2 | 1000 | Københavns Universitet | 10115 | Folkesundhedsvidenskab, København K, Studiesta... | 88 | Uoplyst | NaN |
3 | 1000 | Københavns Universitet | 10117 | Farmaci, København Ø, Studiestart: sommerstart | 291 | Uoplyst | NaN |
4 | 1000 | Københavns Universitet | 10120 | Odontologi, København Ø, Studiestart: sommerstart | 471 | Uoplyst | 1 |
... | ... | ... | ... | ... | ... | ... | ... |
14875 | 8800 | Erhvervsakademi Dania | 84410 | Produktionsteknolog, Randers SØ, Studiestart: ... | 6 | 15.0 | NaN |
14876 | 8800 | Erhvervsakademi Dania | 86160 | Service- og oplevelsesøkonom, Randers SØ, Stud... | 15 | 15.0 | NaN |
14877 | 8800 | Erhvervsakademi Dania | 86164 | Service- og oplevelsesøkonom, Randers SØ, E-læ... | 45 | 15.0 | 1.0 |
14878 | 8800 | Erhvervsakademi Dania | 86166 | Service- og oplevelsesøkonom, Randers SØ, E-læ... | 9 | 15.0 | NaN |
14879 | 8800 | Erhvervsakademi Dania | 87110 | Logistikøkonom , Hobro, Studiestart: sommerstart | 15 | 15.0 | NaN |
14880 rows × 7 columns
Ny mangler vi dog at “mappe” de forskelle adgangsgrundlag id’er sådan at der står det faktiske adgangsgrundlag og ikke tallet.
= {}
d for index, row in adgange.iterrows():
float(row["id"])] = row["adgangsgrundlag"]
d[
d
{1.0: 'stx',
2.0: 'hf',
3.0: 'hhx',
4.0: 'htx',
5.0: 'International Baccalaureate (IB)',
6.0: 'GIF',
7.0: 'Adgangseksamen for ingeniøruddannelser',
8.0: 'Erhvervsuddannelse (EUD)',
9.0: 'Andet adgangsgrundlag',
10.0: 'International Baccalaureate (IB) fra udlandet',
11.0: 'Anden adgangsgivende eksamen fra ud-landet',
12.0: 'eux',
13.0: 'eux 1. del',
14.0: 'Færøsk gymnasial eksamen',
15.0: 'Grønlandsk gymnasial eksamen'}
'future.no_silent_downcasting', False)
pd.set_option(#melted[18] = melted[18].replace("Uoplyst", np.nan).infer_objects(copy=False)
"adgangsgrundlag"] = melted[18].map(d) melted[
= melted.drop(columns=18) melted
= melted.rename(columns={"value": "antal"}) melted
"adgangsgrundlag"] = melted["adgangsgrundlag"].replace(np.nan, "Uoplyst").infer_objects(copy=False) melted[
melted
InstNr | InstNavn | OptNr | OptNavn | I alt | antal | adgangsgrundlag | |
---|---|---|---|---|---|---|---|
0 | 1000 | Københavns Universitet | 10110 | Medicin, København Ø, Studiestart: sommer- og ... | 1687 | 4 | Uoplyst |
1 | 1000 | Københavns Universitet | 10112 | Medicin, Køge, Studiestart: sommer- og vinters... | 234 | NaN | Uoplyst |
2 | 1000 | Københavns Universitet | 10115 | Folkesundhedsvidenskab, København K, Studiesta... | 88 | NaN | Uoplyst |
3 | 1000 | Københavns Universitet | 10117 | Farmaci, København Ø, Studiestart: sommerstart | 291 | NaN | Uoplyst |
4 | 1000 | Københavns Universitet | 10120 | Odontologi, København Ø, Studiestart: sommerstart | 471 | 1 | Uoplyst |
... | ... | ... | ... | ... | ... | ... | ... |
14875 | 8800 | Erhvervsakademi Dania | 84410 | Produktionsteknolog, Randers SØ, Studiestart: ... | 6 | NaN | Grønlandsk gymnasial eksamen |
14876 | 8800 | Erhvervsakademi Dania | 86160 | Service- og oplevelsesøkonom, Randers SØ, Stud... | 15 | NaN | Grønlandsk gymnasial eksamen |
14877 | 8800 | Erhvervsakademi Dania | 86164 | Service- og oplevelsesøkonom, Randers SØ, E-læ... | 45 | 1.0 | Grønlandsk gymnasial eksamen |
14878 | 8800 | Erhvervsakademi Dania | 86166 | Service- og oplevelsesøkonom, Randers SØ, E-læ... | 9 | NaN | Grønlandsk gymnasial eksamen |
14879 | 8800 | Erhvervsakademi Dania | 87110 | Logistikøkonom , Hobro, Studiestart: sommerstart | 15 | NaN | Grønlandsk gymnasial eksamen |
14880 rows × 7 columns
# Finde InstNavn for CBS
"InstNavn"].unique() melted[
array(['Københavns Universitet',
'Copenhagen Business School - Handelshøjskolen',
'IT-Universitetet i København', 'Danmarks Tekniske Universitet',
'Roskilde Universitet', 'Syddansk Universitet',
'Aarhus Universitet', 'Aalborg Universitet',
'Det Kongelige Akademi - Arkitektur, Design, Konservering',
'Arkitektskolen Aarhus', 'Designskolen Kolding',
'Københavns Professionshøjskole', 'Professionshøjskolen Absalon',
'Professionshøjskolen UC Syddanmark',
'UCL Erhvervsakademi og Professionshøjskole',
'Professionshøjskolen VIA University College',
'Professionshøjskolen University College Nordjylland',
'Danmarks Medie- og Journalisthøjskole', 'Den Frie Lærerskole',
'Maskinmesterskolen København',
'Svendborg International Maritime Academy, SIMAC',
'Fredericia Maskinmesterskole', 'Aarhus Maskinmesterskole',
'MARTEC - Maritime and Polytechnic University College',
'Erhvervsakademiet Copenhagen Business Academy',
'Københavns Erhvervsakademi (KEA)',
'Zealand Sjællands Erhvervsakademi', 'IBA Erhvervsakademi Kolding',
'Erhvervsakademi SydVest', 'Erhvervsakademi MidtVest',
'Erhvervsakademi Aarhus', 'Erhvervsakademi Dania'], dtype=object)
# Filtrere CBS
= melted[melted["InstNavn"] == "Copenhagen Business School - Handelshøjskolen"] CBS
CBS
InstNr | InstNavn | OptNr | OptNavn | I alt | antal | adgangsgrundlag | |
---|---|---|---|---|---|---|---|
75 | 1300 | Copenhagen Business School - Handelshøjskolen | 13010 | Erhvervsøkonomi, HA, Frederiksberg, Studiestar... | 925 | NaN | Uoplyst |
76 | 1300 | Copenhagen Business School - Handelshøjskolen | 13015 | Erhvervsøkonomi-informationsteknologi, HA (it.... | 223 | NaN | Uoplyst |
77 | 1300 | Copenhagen Business School - Handelshøjskolen | 13020 | Erhvervsøkonomi-erhvervsret, HA (jur.), Freder... | 305 | NaN | Uoplyst |
78 | 1300 | Copenhagen Business School - Handelshøjskolen | 13023 | Erhvervsøkonomi og markeds- og kulturanalyse, ... | 251 | NaN | Uoplyst |
79 | 1300 | Copenhagen Business School - Handelshøjskolen | 13025 | Erhvervsøkonomi-matematik, HA (mat.), Frederik... | 89 | NaN | Uoplyst |
... | ... | ... | ... | ... | ... | ... | ... |
14039 | 1300 | Copenhagen Business School - Handelshøjskolen | 13085 | Business, Asian Language and Culture - Interna... | 71 | NaN | Grønlandsk gymnasial eksamen |
14040 | 1300 | Copenhagen Business School - Handelshøjskolen | 13090 | Business, Asian Language and Culture - Interna... | 72 | NaN | Grønlandsk gymnasial eksamen |
14041 | 1300 | Copenhagen Business School - Handelshøjskolen | 13100 | Business Administration and Digital Management... | 601 | NaN | Grønlandsk gymnasial eksamen |
14042 | 1300 | Copenhagen Business School - Handelshøjskolen | 13280 | International Shipping and Trade, Frederiksber... | 272 | NaN | Grønlandsk gymnasial eksamen |
14043 | 1300 | Copenhagen Business School - Handelshøjskolen | 13290 | Europæisk business, HA i europæisk business, F... | 273 | NaN | Grønlandsk gymnasial eksamen |
304 rows × 7 columns
Tilføjelse af procent kolonne
import altair as alt
# lave ny kolonnen med procent af total med givne adgangsgrundlag
"procent"] = (melted["antal"] / melted["I alt"]) melted[
melted.dtypes
InstNr object
InstNavn object
OptNr object
OptNavn object
I alt object
antal object
adgangsgrundlag object
procent object
dtype: object
'procent'].astype('float') melted[
0 0.002371
1 NaN
2 NaN
3 NaN
4 0.002123
...
14875 NaN
14876 NaN
14877 0.022222
14878 NaN
14879 NaN
Name: procent, Length: 14880, dtype: float64
= melted[(melted['InstNr']== 1300) & (melted['adgangsgrundlag'] == 'stx')] cbs_stx
alt.Chart(cbs_stx).mark_point().encode(=alt.Y('OptNavn', axis=alt.Axis(labelAngle=0, labelLimit=0, titlePadding=400)),
y="procent"
x )
Her kan man altså se procentandelen af studerende for hver CBS Bachelor uddannelse, hvor den studerende har STX som adgangsgrundlag. Her giver det mening at de uddannelse med en STX procent på under 0.3 er på engelsk, hvor er vil være mange udenlandske studerende som derfor ikke har gået på STX. De engelske uddannelse ville give mening at analysere ved at se procentandelen af STX hvor udenlandske studerende er talt fra for at få en ide om hvilke grundlag de danske studerende har.
= melted[melted['InstNr'] == 1300] cbs
'future.no_silent_downcasting', True)
pd.set_option('antal'] = cbs['antal'].fillna(0)
cbs.loc[:, 'procent'] = cbs['procent'].fillna(0) cbs.loc[:,
cbs
InstNr | InstNavn | OptNr | OptNavn | I alt | antal | adgangsgrundlag | procent | |
---|---|---|---|---|---|---|---|---|
75 | 1300 | Copenhagen Business School - Handelshøjskolen | 13010 | Erhvervsøkonomi, HA, Frederiksberg, Studiestar... | 925 | 0 | Uoplyst | 0 |
76 | 1300 | Copenhagen Business School - Handelshøjskolen | 13015 | Erhvervsøkonomi-informationsteknologi, HA (it.... | 223 | 0 | Uoplyst | 0 |
77 | 1300 | Copenhagen Business School - Handelshøjskolen | 13020 | Erhvervsøkonomi-erhvervsret, HA (jur.), Freder... | 305 | 0 | Uoplyst | 0 |
78 | 1300 | Copenhagen Business School - Handelshøjskolen | 13023 | Erhvervsøkonomi og markeds- og kulturanalyse, ... | 251 | 0 | Uoplyst | 0 |
79 | 1300 | Copenhagen Business School - Handelshøjskolen | 13025 | Erhvervsøkonomi-matematik, HA (mat.), Frederik... | 89 | 0 | Uoplyst | 0 |
... | ... | ... | ... | ... | ... | ... | ... | ... |
14039 | 1300 | Copenhagen Business School - Handelshøjskolen | 13085 | Business, Asian Language and Culture - Interna... | 71 | 0 | Grønlandsk gymnasial eksamen | 0 |
14040 | 1300 | Copenhagen Business School - Handelshøjskolen | 13090 | Business, Asian Language and Culture - Interna... | 72 | 0 | Grønlandsk gymnasial eksamen | 0 |
14041 | 1300 | Copenhagen Business School - Handelshøjskolen | 13100 | Business Administration and Digital Management... | 601 | 0 | Grønlandsk gymnasial eksamen | 0 |
14042 | 1300 | Copenhagen Business School - Handelshøjskolen | 13280 | International Shipping and Trade, Frederiksber... | 272 | 0 | Grønlandsk gymnasial eksamen | 0 |
14043 | 1300 | Copenhagen Business School - Handelshøjskolen | 13290 | Europæisk business, HA i europæisk business, F... | 273 | 0 | Grønlandsk gymnasial eksamen | 0 |
304 rows × 8 columns
alt.Chart(cbs).mark_bar().encode(=alt.Y('OptNavn', axis=alt.Axis(labelAngle=0, labelLimit=0, titlePadding=400)),
y="procent",
x='adgangsgrundlag'
color )
Her kan vi se fordelingen af adgangsgrundlag mere tydeligt. Hvor STX og HHX dominerer på de danske uddannelser hos CBS.
Til en videre analyse, ville det være interessant at sammenligne fordelingen med procentandelen af adgangsgrundlagene for STX, HHX osv. for at tyde om HHX’ere i højere grad søger CBS end STX relativt til antal studerende. Desuden at sammenligne med andre erhvervsøkonomiske uddannelser og se hvorledes deres fordelinger er.