6. Moment06 - Dataanalys

Info

Till detta moment finns en sida med lösningsförslag.

I vår alltmer digitaliserade värld genereras stora mängder data varje sekund. Från sociala medier till vetenskapliga experiment, från ekonomiska transaktioner till klimatobservationer, spelar data en central roll i hur vi förstår och påverkar världen omkring oss. Dataanalys är processen att omvandla denna rådata till insikter, kunskap och beslutsunderlag. Genom att använda kraftfulla verktyg och tekniker kan vi extrahera värdefull information från komplexa datamängder, upptäcka mönster, trender och relationer, och på så sätt fatta bättre beslut, förutspå framtida händelser och lösa problem.

Python är ett programmeringsspråk som har blivit synonymt med dataanalys, tack vare sin läsbarhet, flexibilitet och det rika ekosystemet av bibliotek och verktyg. I detta kursmoment kommer vi att utforska två av de mest kraftfulla biblioteken för dataanalys och visualisering: Pandas och Matplotlib.

  • Pandas erbjuder snabba, flexibla och uttrycksfulla datastrukturer som är designade för att göra datahantering och analys intuitiv och effektiv.
  • Matplotlib är ett omfattande bibliotek för att skapa statiska, animerade och interaktiva visualiseringar i Python.

6.1 Moduler, paket och bibliotek

Ni har tidigare lärt er att skapa egna funktioner i Python, vilket är ett kraftfullt sätt att organisera och återanvända kod. Men tänk om ni kunde ta detta ett steg längre och dela era funktioner med andra, eller använda funktioner som andra har skrivit? Här kommer koncepten moduler, paket och bibliotek in i bilden.

6.1.1 Modul

En modul i Python är helt enkelt en fil som innehåller Python-kod. Den kan inkludera funktioner och variabler som du kan använda i andra Python-filer. Genom att skapa moduler kan du organisera ditt program i separata filer som är enklare att hantera och återanvända. Tänk på en modul som en verktygslåda fylld med specifika verktyg du har skapat.

Att skapa en modul är så enkelt som att spara dina funktioner i en ny .py-fil. Låt oss säga att du har en fil som heter my_math_functions.py med några matematiska funktioner du har skrivit. Du kan använda dessa funktioner i ett annat program genom att "importera" modulen med ett `import`-kommando.

Kodexempel: importera en modul

import my_math_functions

result = my_math_functions.add(5, 3)  # Använder en funktion från modulen
print(result)

6.1.2 Paket

I Python är ett paket en mapp som används för att organisera och lagra Python-filer, som kallas moduler. Varje modul är en fil som innehåller Python-kod och kan innehålla funktioner, variabler och andra användbara koddelar.

För större programmeringsprojekt är det praktiskt att dela upp koden i olika moduler för att hålla den organiserad. Dessa moduler kan sedan grupperas i mappar, vilka definieras som paket. Ett paket skiljer sig från en vanlig mapp genom att det innehåller en speciell fil benämnd __init__.py. Denna fil är ofta tom men dess närvaro indikerar för Python att mappen är ett paket och inte bara en vanlig mapp.

Användningen av paket gör det möjligt att strukturera moduler hierarkiskt, vilket underlättar hanteringen av kod när projekten växer sig större. Denna organisationsmetod bidrar till bättre kodöversikt och effektivitet i större projekt.

6.1.3 Bibliotek

Ett bibliotek är en bredare term som oftast refererar till en samling av paket och moduler som är utformade för att användas i andra program. Bibliotek kan innehålla allt från enkla hjälpfunktioner till komplexa system för dataanalys, som Pandas och Matplotlib, vilka vi kommer att utforska. Att använda ett bibliotek innebär att dra nytta av andras kod för att lösa specifika problem utan att behöva uppfinna hjulet på nytt.

6.1.4 Varför använda moduler, paket och bibliotek?

Det finns ett antal anledningar att skapa moduler, paket och bibliotek, här kommer några av fördelarna.

  • Återanvändbarhet: Genom att dela upp din kod i återanvändbara moduler och paket, kan du enkelt återanvända den i andra projekt.
  • Organisation: Moduler och paket hjälper till att hålla din kod organiserad och lättförståelig.
  • Delning: Genom att skapa moduler och paket kan du dela din kod med andra, vilket bidrar till öppen källkodsprojekt och samarbete.

6.1.5 Installera paket

För att kunna använda paket i Python så behöver de installeras så att det är tillgängligt i ditt projekt. Denna installationen kan göras på olika sätt beroende på vilken IDE du använder.

6.1.5.1 PyCharm

  1. Öppna PyCharm och ladda ditt projekt.
  2. Gå till Settings: Använd File > Settings på Windows/Linux eller PyCharm > Settings på macOS.
  3. Navigera till Project Interpreter: Under Project: hittar du Python Interpreter.
  4. Lägg till Paket: Klicka på +-ikonen till höger om listan över installerade paket.
  5. Sök och Installera: Sök efter det paket du vill installera (t.ex., numpy eller pandas) i sökfältet, välj det från listan och klicka på Install Package.

6.1.5.2 Spyder

Om din elev använder Spyder utan Anaconda, kan paketet installeras direkt med pip från terminalen:

  • Öppna en terminal (eller kommandotolk/CMD på Windows).
  • Kör pip-kommandot för att installera önskat paket: pip install numpy

Det är viktigt att se till att pip-kommandot körs i den Python-miljö där Spyder är installerad. Om eleverna använder virtuella miljöer, måste de aktivera den relevanta miljön innan de kör pip-kommandot.

Funkar det på Spyder?

Om detta inte fungerar i Spyder på macOS så undersöker vi tillsammans.

6.2 NumPy

NumPy är en central del av Python som används för vetenskapliga beräkningar. Detta bibliotek är speciellt användbart när du behöver utföra komplexa matematiska och statistiska operationer på ett effektivt och relativt enkelt sätt.

En av de största fördelarna med NumPy är dess förmåga att hantera stora mängder data mycket snabbare än vad som är möjligt med Pythons standardlistor. Detta är möjligt på grund av NumPy's optimerade sätt att hantera data intern. Med andra ord, NumPy är byggt för att utföra beräkningar snabbt och effektivt, vilket gör det till ett kraftfullt verktyg för alla som arbetar med dataanalys och vetenskapliga beräkningar.

Genom att använda NumPy kan programmerare och forskare spara tid och resurser, vilket gör det möjligt att fokusera mer på problemlösning och mindre på tekniska detaljer.

I detta avsnitt kommer vi använda NumPy lite praktiskt men vi kommer inte gå igenom alla möjligheter som finns tillgängliga. För att hitta dokumentation så hittar ni den på NumPy's hemsida.

För att kunna använda NumPy så måste det först installeras enligt avsnitt 6.1.5 ovan. När det väl är installerat så måste det importeras för att kunna användas.

6.2.1 ndarray

I NumPy står ndarray för "n-dimensional array" vilket betyder flerdimensionell array på svenska. En array kan ses som en samling av element som är organiserade i en eller flera dimensioner. En 1D-array liknar en enkel lista med siffror, en 2D-array kan liknas vid en tabell eller matris, och en 3D-array kan tänkas som en stapel av tabeller. En ndarray har vissa egenskaper som skiljer sig från en vanlig lista i Python.

  1. Alla element i en array måste vara av samma datatyp, oftast numeriska typer som heltal eller flyttal. Detta gör det möjligt för NumPy att hantera operationer snabbt och effektivt.
  2. Fast storlek: Till skillnad från Python-listor, som kan växa eller krympa dynamiskt, måste storleken på en NumPy-array bestämmas när den skapas, däremot finns det möjlighet att omforma om en ndarray från t.ex. 1D med sex element till en 2D med 2 rader x 3 kolumner.
  3. Effektivitet: Arrays hanteras och lagras på ett sätt som gör operationer på dem mycket snabbare än motsvarande operationer på Python-listor.

Här är några exempel på hur man skapar och arbetar med NumPy-arrays:

Kodexempel

import numpy as np

# Skapa en enkel array
a = np.array([1, 2, 3, 4, 5])
print(a)

# Addera varje element med 1
print("\n", a+1)

# Multiplicera varje element med 2
print("\n", a*2)

# Skriv ut längden på array a
print("\nAntal element", f"{len(a)} st.", f"Elementen: {a}")

# Skapa en array med ett intervall av tal
b = np.arange(10)
print("\n", b)
# f = np.arange(start=0, stop=10, step=1) gör samma sak

# Skapa en array med likformigt fördelade värden mellan två punkter
c = np.linspace(0, 1, 11)
print("\n", c)

# Skapa en tvådimensionell array
d = np.array([[1, 2, 3], [4, 5, 6]])
print("\n", d)

# Exempel på några operationer
print("\nSumma av alla element i b:", np.sum(d))
print("Medelvärde av elementen i b:", np.mean(d))
print("Lägsta värdet i b:", np.min(d))
print("Högsta värdet i b:", np.max(d))
print("Summa av kolumner:", np.sum(d, axis=0))
print("Summa av raderna:", np.sum(d, axis=1))

# Skapa en array med nollor (2 rader, 3 kolumner)
e = np.zeros((2, 3))
print("\n", e)

# Skapa en array med ettor
f = np.ones((3, 3))
print("\n", f)

# Slumpar värden mellan 1 och 10 i en 5 x 2 2darray
g = np.random.randint(1, 11, size=(5, 2))
print("\n", g)

Utskrift

[1 2 3 4 5]

[2 3 4 5 6]

[ 2  4  6  8 10]

Antal element 5 st. Elementen: [1 2 3 4 5]

[0 1 2 3 4 5 6 7 8 9]

[0.  0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1. ]

[[1 2 3]
[4 5 6]]

Summa av alla element i b: 21
Medelvärde av elementen i b: 3.5
Lägsta värdet i b: 1
Högsta värdet i b: 6
Summa av kolumner: [5 7 9]
Summa av raderna: [ 6 15]

[[0. 0. 0.]
[0. 0. 0.]]

[[1. 1. 1.]
[1. 1. 1.]
[1. 1. 1.]]

[[ 9  7]
[10  8]
[ 7  3]
[ 4  5]
[ 7 10]]

Uppgift: m06u01

Nu skall du få leka lite med ndarray. Gör följande uppgifter och skriv ut värdet på arrayen efter varje uppgift.

  1. Skapa en endimensionell array (1darray) med 11 element som har värdet 11-21. Använd linspace() eller arange()
  2. Öka värdet på varje element med 15%.
  3. Beräkna summan och medelvärdet för arrayen. (Kan du också skriva ut medianen? Finns det olika sätt?)
  4. Skapa en 2darray som är fem kolumner och tre rader stor. Ge alla element värdet 0.
  5. I Numpy så kan man slumpa värden när en ndarray skapas. "np.random.randint(1, 11, size=(5, 3))" skapar en 2darray med 5 rader och 3 kolumner.
    Skapa nu en 2darray som simulerar 10 personer som slår två tärningsslag med en tärning, personerna lagras i rader, tärningsslagen (1-6) i kolummer.
    Summera alla spelares resultat (summan av tärningsslagen) samt summera alla spelares "förstaslag" respektive "andraslag" för att se vilket som var bäst.
  6. (Svårare) Om du lagrar summan av varje rad i en egen array så kan du med numpyfunktionen argmax() ta fram indexet på raden med det högsta värdet. Skriv ut den "tärningsserien" med bäst resultat.

6.2.2 Skapa 1darray från fil

Här kommer ett exempel på hur man läser in en 1darray från en fil.

Kodexempel

import numpy as np

# Läsa in data från filen
resultat = np.loadtxt('prov01.txt')

# Skriv ut de inlästa datan
print(f"Alla resultat: {resultat}")

# Sortera
resultat_sort = np.sort(resultat)
print(f"Sorterad: {resultat_sort}")

# Sortera i omvänd ordning
resultat_sort = np.sort(resultat)[::-1]
print(f"Omvänt sorterad: {resultat_sort}")

# Beräkna och skriv ut statistiska mått
min_value = np.min(resultat)
max_value = np.max(resultat)
mean_value = np.mean(resultat)
median_value = np.median(resultat)

print(f"Minimum: {min_value}")
print(f"Maximum: {max_value}")
print(f"Medelvärde: {mean_value}")
print(f"Median: {median_value}")

# Skapa en boolesk array där varje position indikerar om värdet är över medelvärdet
over_medel = resultat > mean_value
print(over_medel)

# Använd np.sum() på den booleska arrayen för att räkna antalet 'True'-värden
print(f"Antal värden över medelvärdet: {np.sum(over_medel)}")

prov01.txt [klicka för att visa]

25
22
18
30
27

Utskrift

Alla resultat: [25. 22. 18. 30. 27.]
Sorterad: [18. 22. 25. 27. 30.]
Omvänt sorterad: [30. 27. 25. 22. 18.]
Minimum: 18.0
Maximum: 30.0
Medelvärde: 24.4
Median: 25.0
[ True False False  True  True]
Antal värden över medelvärdet: 3

Uppgift: m06u02

Skapa en fil i ditt projekt som du döper till provpoäng.txt kopiera sedan filens innehåll nedan till den filen du skapat. Filen innehåller 25 tal från 1 till 100. Exempelinnehållet skapas om ifall du laddar om sidan.

  1. Skriv ut talen sorterat från det lägsta till högsta.
  2. Skriv ut hur många tal som finns i listan (utgå ifrån att du inte vet hur många tal provpoäng.txt innehåller).
  3. Skriv ut medelvärdet av talen.
  4. Skriv ut medianvärdet.
  5. Lägg till ett tal i provpoäng.txt och se om du behöver ändra något i din kod för att den skall fungera?
  6. Jämför din lösning med m05u08, fundera på skillnader och likheter.

provpoäng.txt [klicka för att visa]

100
34
46
21
80
53
39
11
29
24
82
9
92
70
80
36
70
10
97
95
27
73
3
46
50

6.2.3 Skapa 2darray från fil

Här kommer ett exempel på hur man läser in en 2darray från en fil.

Kodexempel

import numpy as np

# Inläsning
data = np.loadtxt('prov02.csv', delimiter=';')
# Skriv ut hela arrayen
print(f"Skriver ut hela 2darrayen:\n{data}")

# Beräkna slutpoäng för varje elev (rad) genom att summera delresultaten
slutpoäng = np.sum(data, axis=1)
print(f"\nSumman för varje elev: {slutpoäng}")

# Beräkna summan av varje delprov
delprov = np.sum(data, axis=0)
print(f"\nSumman av varje delprov: {delprov}")

# Beräkna medelvärdet av varje elevs resultat
medelvardet_per_elev = np.mean(data, axis=1)
medelvardet_per_delprov = np.mean(data, axis=0)

print(f"\nMedelvärde per elev: {medelvardet_per_elev}")
print(f"Medelvärde per delprov: {medelvardet_per_delprov}")

print("\nSkriv ut varje elev för sig")
# Skapa en strängrepresentation av varje elevs medelvärde, avrundat till 2 decimaler, och skriv ut
for index, medel in enumerate(medelvardet_per_elev, start=1):
    print(f"Elev {index}: {medel:.2f}")

print("\nSkriv ut i sorterad ordning")
# Sortera elevernas medelvärden i fallande ordning
# Detta visar elevernas medelvärden sorterade från högsta till lägsta. Varje elevs identifierare här är deras
# position i den ursprungliga datamängden, justerad efter sorteringen.
# np.argsort ger indexen som skulle sortera arrayen, och [::-1] inverterar ordningen till fallande
sorterade_index = np.argsort(medelvardet_per_elev)[::-1]

# Använd de sorterade indexen för att skriva ut elevernas medelvärden i sorterad ordning
for index in sorterade_index:
    medel = medelvardet_per_elev[index]
    print(f"Elev {index+1}: {medel:.2f}")

prov02.csv [klicka för att visa]

9;7;6
8;8;2
10;10;8
4;5;1
7;5;6

CSV

Detta är en filtyp vi inte pratat om tidigare, csv står för Comma-Separated Values och är en fil där varje element separeras av ett kommatecken. Men det är vanligt att använda semikolon (;) som avgränsare.

Utskrift

Skriver ut hela 2darrayen:
[[ 9.  7.  6.]
 [ 8.  8.  2.]
 [10. 10.  8.]
 [ 4.  5.  1.]
 [ 7.  5.  6.]]

Summan för varje elev: [22. 18. 28. 10. 18.]

Summan av varje delprov: [38. 35. 23.]

Medelvärde per elev: [7.33333333 6.         9.33333333 3.33333333 6.        ]
Medelvärde per delprov: [7.6 7.  4.6]

Skriv ut varje elev för sig
Elev 1: 7.33
Elev 2: 6.00
Elev 3: 9.33
Elev 4: 3.33
Elev 5: 6.00

Skriv ut i sorterad ordning
Elev 3: 9.33
Elev 1: 7.33
Elev 5: 6.00
Elev 2: 6.00
Elev 4: 3.33

Ingen uppgift

Här finns ingen uppgift, men om du vill testa på egen hand med att läsa in en 2darray från en fil så finns många av de funktioner som kan behövas i avsnitt 6.2.1.

Så långt fungerar NumPy och ndarrayer väldigt bra men grundkravet för en ndarray är att alla värden i den har samma datatyp. Om vi behöver blanda datatyper så kommer det inte lägre att fungera och då behöver vi hitta ett annat paket som hjälper oss med detta. Så om vi behöver jobba med en fil som nedan så kommer det inte fungera med NumPy.

prov03.csv

Anna;9;7;6
Bosse;8;8;2
Ceasar;10;10;8
Diane;4;5;1
Egon;7;5;6

Pandas heter det paket som kan jobba med den filens innehåll, Pandas bygger på NumPy och vi kika vidare på Pandas i nästa avsnitt.

6.3 Pandas

Pandas är ett öppen källkods-bibliotek som tillhandahåller högpresterande, lättanvända datastrukturer och dataanalysverktyg för Python. Dess mest centrala funktioner baseras på två datastrukturer: Series och DataFrame.

  • En Series är en endimensionell array-liknande struktur som kan lagra vilken datatyp som helst.
  • En DataFrame är en tvådimensionell tabell, likt ett kalkylblad, där varje kolumn kan ha sin egen datatyp. Det är Pandas mest kraftfulla verktyg och möjliggör hantering av komplexa datamängder på ett intuitivt sätt.

Varför används Pandas? Pandas DataFrames tillåter dig att enkelt läsa, skriva och modifiera datatabeller med olika datatyper, vilket skapar en större flexibilitet. Med Pandas kan du enkelt utföra operationer som filtrering, gruppering, och aggregering av data, vilket är en förutsättning för att hantera data på ett bra sätt. Pandas innehåller många inbyggda funktioner för att snabbt och effektivt utforska och analysera data. Pandas fungerar väl ihop med både NumPy och Matplotlib, vilket gör det till ett kraftfullt verktyg för både dataanalys och visualisering.

Precis som med NumPy så kommer jag bara introducera och testa några funktioner, vill du dyka djupare i Pandas så finns det väldigt mycket resurser på nätet och Pandas dokumentation är alltid en bra källa till kunskap.

6.3.1 Series

Vi börjar kika på Series och tar avstamp i numpy för att kika på likheter och skillnader dem emellan.

Här kommer ett exempel på hur man läser in en 2darray från en fil.

Kodexempel

import numpy as np
import pandas as pd

# Skapa en lista med heltal
data = [10, 20, 30, 40, 50]

# Skapa en NumPy array
numpy_array = np.array(data)
print("NumPy Array:")
print(numpy_array * 2)  # Multiplicera varje element med 2

# Skapa en Pandas Series
pandas_series = pd.Series(data)
print("\nPandas Series:")
print(pandas_series * 2)  # Multiplicera varje element med 2

Utskrift

NumPy Array:
[ 20  40  60  80 100]

Pandas Series:
0     20
1     40
2     60
3     80
4    100
dtype: int64

Vid utskriften så ser du skillnad på hur de olika strukturerna lagras och skrivs ut. En annan sak att notera är utskriften dtype: int64 vilket noterar vilken datatyp Series har. Att förstå och hantera datatyper är en grundläggande del av att arbeta med Pandas och dataanalys i Python, vilket hjälper till att säkerställa att datan hanteras korrekt genom alla stadier av en analys. Så länge vi jobbar med data som kommer med rätt datatyp så kommer det inte vara några problem och skulle vi få in data som inte har rätt datatyp så får vi lösa det problemet då.

Vi testar att göra lite statistiska beräkningar på vår Pandas.Series på samma sätt som vi gjorde med NumPy tidigare. Som du kan se så finns de funktioner vi använde i NumPy även när det gäller Pandas, de anropas bara lite annorlunda.

Kodexempel

import pandas as pd

s = pd.Series([-4, 22, 9, 12, 8])   # Skapa en Pandas Series
print(s)
print("Statistik")
print("Sorterat:", s.sort_values()) # Sorterad från lägst till högst
print("Summa:", s.sum())            # Summera elementen i serien
print("Högsta värde:", s.max())     # Beräkna högsta värdet
print("Lägsta värde:", s.min())     # Beräkna lägsta värdet
print("Medelvärde:", s.mean())      # Beräkna medelvärdet
print("Median:", s.median())        # Beräkna medianen
print("Antal värden:", s.count())   # Antalet element

Utskrift

0    -4
1    22
2     9
3    12
4     8
dtype: int64
Statistik
Sorterat: 0    -4
4     8
2     9
3    12
1    22
dtype: int64
Summa: 47
Högsta värde: 22
Lägsta värde: -4
Medelvärde: 9.4
Median: 9.0
Antal värden: 5

Såg du skillnaden? När vi jobbade med NumPy så tillhörde funktionen t.ex. min() paketet NumPy,np.min(resultat), medan den nu tillhör variabeln av typen Series, s.max(). Det är som vanligt viktigare att vi kan använda det än att vi kan det utantill.

Att läsa in data från en textfil till Series görs enkelt med funktionen pd.read_csv() vilket fungerar även om det inte är en csv-fil som vi läser in.

Kodexempel

import pandas as pd

# Läs in filen som en Pandas DataFrame
data_df = pd.read_csv("prov01.txt", header=None)

# Konvertera DataFrame till Series
data_series = data_df.squeeze()  # Använd squeeze() för att konvertera en enda kolumn DataFrame till Series

# Om det finns flera kolumner i ett DataFram så kan du välja vilken som skall konverteras
data_series = data_df[0].squeeze()

# Skriv ut Series
print(data_series)

Utskrift

0    25
1    22
2    18
3    30
4    27
Name: 0, dtype: int64

Uppgift: m06u03

Detta är samma uppgift som m06u02 fast vi nu använder Pandas och vi använder Series istället för en ndarray. Här kan det finnas en poäng i att du tar en kopia av din lösning i m06u02 och gör samma lösning fast nu med strukturen Pandas.Series för att du enkelt skall kunna se likheter och skillnader.

Skapa en fil i ditt projekt som du döper till provpoäng.txt kopiera sedan filens innehåll nedan till den filen du skapat. Filen innehåller 25 tal från 1 till 100. Exempelinnehållet skapas om ifall du laddar om sidan.

  1. Skriv ut talen sorterat från det lägsta till högsta.
  2. Skriv ut hur många tal som finns i listan (utgå ifrån att du inte vet hur många tal provpoäng.txt innehåller).
  3. Skriv ut medelvärdet av talen.
  4. Skriv ut medianvärdet.
  5. Lägg till ett tal i provpoäng.txt och se om du behöver ändra något i din kod för att den skall fungera?
  6. Jämför din lösning med m06u02, fundera på skillnader och likheter.

provpoäng.txt [klicka för att visa]

100
34
46
21
80
53
39
11
29
24
82
9
92
70
80
36
70
10
97
95
27
73
3
46
50

6.3.2 DataFrame

Då skall vi kika på nästa datastruktur i Pandas som heter DataFrame vilket är en datastruktur som liknar en tvådimensionell tabell, som i ett kalkylark, där varje kolumn kan ha sin egna datatyp. Denna struktur ger oss mängder av möjligheter som vi skall kika på genom några exempel.

6.3.2.1 Läs in från fil

Vi börjar med att läsa in från en semikolonseparerad CSV-fil och gör om till ett DataFrame.

Kodexempel

import pandas as pd

# Läs in data från CSV-filen till en DataFrame
df = pd.read_csv('prov03.csv',  # Filens namn
                 delimiter=';', # Avdelare
                 header=None,   # Inga kolumnrubriker finns i filen
                 names=['Namn', 'Prov1', 'Prov2', 'Prov3']) # Skapa kolumnrubriker

# Skriv ut hela DataFrame
print(df)

# Om det hade funnits kolumnrubriker på första raden i den inlästa filen
# "Namn;Prov1;Prov2;Prov3"
# Då hade det räckt att läsa in df på följande sätt
# df = pd.read_csv('prov03.csv', delimiter=';')

prov03.csv

Anna;9;7;6
Bosse;8;8;2
Ceasar;10;10;8
Diane;4;5;1
Egon;7;5;6

Utskrift

       Namn  Prov1  Prov2  Prov3
  0    Anna      9      7      6
  1   Bosse      8      8      2
  2  Ceasar     10     10      8
  3   Diane      4      5      1
  4    Egon      7      5      6

Det var ju snyggt, men nu skall vi testa att jobba med denna strukturen. Vad kan vi göra med den?

6.3.2.2 Grundläggande beräkningar, sorteringar och filtreringar

I detta exemplet finns kod för att lägga till beräknade kolumner, välja vilka kolumner som skrivs ut, skriva ut sorterat eller ett särskilt index.

Kodexempel

import pandas as pd

# Läs in data från CSV-filen
df = pd.read_csv('prov03.csv',  # Filens namn
                 delimiter=';', # Avdelare
                 header=None,   # Inga kolumnrubriker finns i filen
                 names=['Namn', 'Prov1', 'Prov2', 'Prov3']) # Skapa kolumnrubriker

# Beräkna totalpoäng för varje elev, lägg till en kolumn i df
df['Totalt'] = df[['Prov1', 'Prov2', 'Prov3']].sum(axis=1)
df['Medel'] = df[['Prov1', 'Prov2', 'Prov3']].mean(axis=1)

# Skriv ut df
print("DataFrame med nya kolumnen Totalt och Medel")
print(df)

# Skriv endast ut Namn och totalpoängen
print("\nUtskrift av bara namn och totalpoäng")
print(df[['Namn', 'Totalt']])

# Skriv endast ut Namn och totalpoängen
print("\nUtskrift av bara namn och totalpoäng, sorterad på totalpoäng högst -> lägst.")
print(df[['Namn', 'Totalt']].sort_values('Totalt', ascending=False))

# Identifiera och skriv ut eleven med högsta totalpoängen
top_student = df.loc[df['Totalt'].idxmax()]
print(f"\nEleven med högsta totalpoängen: {top_student['Namn']} med totalpoäng {top_student['Totalt']}")

# Beräkna summan av poäng för varje delprov över alla elever
# När man summerar över flera kolumner i ett dataframe så blir resultatet
# en Series.
sum_Provs = df[['Prov1', 'Prov2', 'Prov3']].sum()

# Skriv ut summeringen av varje delprov
# Sorteringen av en Series blir annorlunda än ett dataFrame, se rad 22 som exempel
print("\nSumma poäng för varje delprov:")
print(sum_Provs.sort_values(ascending=False))

# Identifiera vilket delprov som genererade mest poäng
max_Prov_prov = sum_Provs.idxmax()
max_Prov_value = sum_Provs.max()

print(f"\nDelprovet som genererade mest poäng var '{max_Prov_prov}' med totalt {max_Prov_value} poäng.")

prov03.csv

Anna;9;7;6
Bosse;8;8;2
Ceasar;10;10;8
Diane;4;5;1
Egon;7;5;6

Utskrift

DataFrame med nya kolumnen Totalt och Medel
     Namn  Prov1  Prov2  Prov3  Totalt     Medel
0    Anna      9      7      6      22  7.333333
1   Bosse      8      8      2      18  6.000000
2  Ceasar     10     10      8      28  9.333333
3   Diane      4      5      1      10  3.333333
4    Egon      7      5      6      18  6.000000

Utskrift av bara namn och totalpoäng
     Namn  Totalt
0    Anna      22
1   Bosse      18
2  Ceasar      28
3   Diane      10
4    Egon      18

Utskrift av bara namn och totalpoäng, sorterad på totalpoäng högst -> lägst.
     Namn  Totalt
2  Ceasar      28
0    Anna      22
1   Bosse      18
4    Egon      18
3   Diane      10

Eleven med högsta totalpoängen: Ceasar med totalpoäng 28

Summa poäng för varje delprov:
Prov1    38
Prov2    35
Prov3    23
dtype: int64

Delprovet som genererade mest poäng var 'Prov1' med totalt 38 poäng.

Här behöver vi stanna till vid det utskrivna medelvärdet som har sex decimaler och så kanske vi inte vill ha det. Om vi tex vill visa upp medelvärdet med två decimaler så finns det två alternativ, vill vi visa upp två decimaler vid utskrift eller vill vi lagra två decimaler?

Kodexempel

## Avrunda vid utskrift
# Gör beräkningen som vi gjort tidigare
df['Medel'] = df[['Prov1', 'Prov2', 'Prov3']].mean(axis=1)
# Avrunda inför utskrift
df['Medel'] = df['Medel'].round(2)
# Skriv ut DataFrame
print(df)

## Avrunda vid lagring
# Beräkna och avrunda innan lagring
df['Medel'] = df[['Prov1', 'Prov2', 'Prov3']].mean(axis=1).round(2)

## Sätt inställningen globalt
# Nu kommer alla flyttal skrivas ut med två decimaler i hela Pandas-sessionen
pd.options.display.float_format = '{:,.2f}'.format

6.3.2.3 Lägg till och ta bort rader i ett dataFrame

Vi jobbar vidare med samma dataframe men nu skapar vi det på ett annat sätt, lägger till elever till ett redan skapat dataframe och tar också bort elever.

Kodexempel

import pandas as pd

# Skapar en dictionary med samma värden som lästes från prov03.csv
data = {
    'Namn': ['Anna', 'Bosse', 'Ceasar', 'Diane', 'Egon'],
    'Prov1': [9, 8, 10, 4, 7],
    'Prov2': [7, 8, 10, 5, 5],
    'Prov3': [6, 2, 8, 1, 6]
}

# Gör om till en dataframe
df = pd.DataFrame(data)

# Data att lägga till
new_students = pd.DataFrame({
    'Namn': ['Figaro', 'Guido'],
    'Prov1': [4, 8],
    'Prov2': [3, 6],
    'Prov3': [2, 5]
})

# Använd pd.concat för att lägga till de nya eleverna
df = pd.concat([df, new_students], ignore_index=True)

# Skapa en DataFrame för den nya eleven Hugo
new_student_df = pd.DataFrame({
    'Namn': ['Hugo'],
    'Prov1': [5],
    'Prov2': [7],
    'Prov3': [9]
})

# Använd pd.concat för att lägga till den nya eleven
df = pd.concat([df, new_student_df], ignore_index=True)

# Hitta index för 'Figaro'
figaro_index = df.index[df['Namn'] == 'Figaro'].tolist()

# Vill vi ta bort en elev ur vår DataFrame kan vi göra på två sätt
# 1. Ta bort elev med ett visst index
df = df.drop(index=3)
# 2. Ta bort eleven som heter Figaro (egentligen skapas ett nytt df utan 'Figaro'
df = df[df['Namn'] != 'Figaro']

print(df)

Utskrift

     Namn  Prov1  Prov2  Prov3
0    Anna      9      7      6
1   Bosse      8      8      2
2  Ceasar     10     10      8
4    Egon      7      5      6
6   Guido      8      6      5
7    Hugo      5      7      9

6.3.2.4 Filtrera

Nu är det dags att filtrera ut specifika saker vi vill visa i ett dataFrame.

Kodexempel

import pandas as pd

# Befintlig DataFrame
data = {
    'Namn': ['Anna', 'Bosse', 'Ceasar', 'Diane', 'Egon', 'Figaro', 'Guido', 'Hugo'],
    'Prov1': [9, 8, 10, 4, 7, 4, 8, 5],
    'Prov2': [7, 8, 10, 5, 5, 3, 6, 7],
    'Prov3': [6, 2, 8, 1, 6, 2, 5, 9]
}
df = pd.DataFrame(data)
print("Samtliga poster i df")
print(df)

# Filtrera DataFrame för att visa enbart de poster där 'Prov3' är minst 5 poäng
filtered_df = df[df['Prov3'] >= 5]
# Skriver du ut df['Prov3'] >= 5 så får du en dataFrame med index och boolvärden

print("\nVisa dataFrame som matchar villkoret (prov3 >= 5)")
print(filtered_df)

# Beräkna totalpoängen för varje elev och lägg till det som en ny kolumn i DataFrame
df['Totalpoäng'] = df['Prov1'] + df['Prov2'] + df['Prov3']

# Använd ett kombinerat filter för att välja ut poster där 'Prov3' är minst 5 poäng och totalpoängen är minst 20 poäng
filtered_df = df[(df['Prov3'] >= 5) & (df['Totalpoäng'] >= 20)]
print("\nVisa dataFrame som matchar villkoren (prov3 >= 5 och Totalpoäng >= 20)")
print(filtered_df)

Utskrift

Samtliga poster i df
     Namn  Prov1  Prov2  Prov3
0    Anna      9      7      6
1   Bosse      8      8      2
2  Ceasar     10     10      8
3   Diane      4      5      1
4    Egon      7      5      6
5  Figaro      4      3      2
6   Guido      8      6      5
7    Hugo      5      7      9

Visa dataFrame som matchar villkoret (prov3 >= 5)
     Namn  Prov1  Prov2  Prov3
0    Anna      9      7      6
2  Ceasar     10     10      8
4    Egon      7      5      6
6   Guido      8      6      5
7    Hugo      5      7      9

Visa dataFrame som matchar villkoren (prov3 >= 5 och Totalpoäng >= 20)
     Namn  Prov1  Prov2  Prov3  Totalpoäng
0    Anna      9      7      6          22
2  Ceasar     10     10      8          28
7    Hugo      5      7      9          21

6.3.2.5 Gruppera och pivottabell

Ibland vill man summera data när den är grupperad. Här grupperar vi och visar upp data på olika sätt.

Kodexempel


import pandas as pd

# Skapa en DataFrame
data = {
    'Butik': ['Butik1', 'Butik1', 'Butik2', 'Butik2', 'Butik1', 'Butik3', 'Butik3'],
    'Frukt': ['Äpple', 'Banan', 'Äpple', 'Banan', 'Banan', 'Äpple', 'Banan'],
    'Mängd': [30, 21, 15, 17, 22, 13, 29]
}
df = pd.DataFrame(data)

print("\nSkriv ut DataFrame")
print(df)

# Gruppera datan efter 'Frukt' och summera 'Mängd'
# grupperad_summa blir då en Pandas.Series
grupperad_summa = df.groupby('Frukt')['Mängd'].sum()
print("\nSkriv ut grupperat data på frukt")
print(grupperad_summa)

# Gruppera datan efter 'Butik' och sedan 'Frukt', och summera 'Mängd'
grupperad_summa = df.groupby(['Butik', 'Frukt'])['Mängd'].sum()

# Skriv ut resultatet
print("\nSkriv ut grupperat data på butik och frukt")
print(grupperad_summa)

# Skapa en pivot table
pivot_df = df.pivot_table(index='Butik', columns='Frukt', values='Mängd', aggfunc='sum', fill_value=0)

# Visa pivot table
print("\nSkriv ut en pivottabell (beräkningar i tabellform)")
print(pivot_df)

Utskrift

Skriv ut DataFrame
    Butik  Frukt  Mängd
0  Butik1  Äpple     30
1  Butik1  Banan     21
2  Butik2  Äpple     15
3  Butik2  Banan     17
4  Butik1  Banan     22
5  Butik3  Äpple     13
6  Butik3  Banan     29

Skriv ut grupperat data på frukt
Frukt
Banan    89
Äpple    58
Name: Mängd, dtype: int64

Skriv ut grupperat data på butik och frukt
Butik   Frukt
Butik1  Banan    43
        Äpple    30
Butik2  Banan    17
        Äpple    15
Butik3  Banan    29
        Äpple    13
Name: Mängd, dtype: int64

Skriv ut en pivottabell (beräkningar i tabellform)
Frukt   Banan  Äpple
Butik               
Butik1     43     30
Butik2     17     15
Butik3     29     13

Uppgift: m06u04

ALS Systemsälj AB har levererat försäljningsstatistiken för sina fyra kontor uppdelat på varje säljares försäljning kvartalsvis. Alla siffror är i tusental.

Din uppgift är att lösa uppgifterna nedan. Många av deluppgifterna bygger vidare på varandra, skapa lämplig utskrift efter varje deluppgift.

  1. Läs in som en CSV-fil till en Pandas DataFrame.
  2. Beräkna total försäljning för varje säljare över året samt genomsnittlig kvartalsförsäljning.
  3. Sortera säljarna efter total försäljning i fallande ordning.
  4. Summera alla kvartalens försäljningar för att få redan på vilket kvartal som hade bäst försäljning.
  5. Skriv ut alla säljare som har sålt för minst en miljon.
  6. Summera total försäljning per kontor för att se vilket kontor som presterar bäst.
  7. Beräkna snittförsäljningen för varje kontor utifrån total försäljning.

Här kommer lite svårare uppgifter.

  1. Gruppera på kontor och respektiver kvartal. Visa också upp det som en pivottabell.
  2. VD:n funderar på att ge bonus på 20% för allt över en miljon som en säljare sålt på årsbasis.
    • Räkna ut hur mycket varje säljare skulle få i bonus.
    • Hur mycket skulle företaget betala ut i bonus?
    • Hur stor procent av försäljningsintäkter skulle betalas ut i bonus?
    • Gruppera kontoren efter hur mycket bonus de anställda på respektive kontor skulle få totalt.

TIPS: Vissa beräkningar kan behöva ske i flera steg, se då till att du planerar lösningen på ett bra sätt. Matematiskt/logiskt bör det inte vara några problem att lösa uppgifterna, att få till koden kräver som vanligt att lösningen är klar innan.

Försäljningsstatistik 2023 [klicka för att visa]

Namn,Kontor,Q1,Q2,Q3,Q4
Maria,Väst,227,421,248,301
Ceasar,Syd,132,157,327,483
Paul,Väst,131,391,379,100
Olga,Öst,302,458,307,494
John,Väst,344,219,497,470
Anita,Öst,251,367,473,143
Raj,Syd,263,182,441,483
Chen,Norr,470,191,148,123
Samir,Öst,283,484,405,287
Elena,Öst,128,498,169,230
Bosse,Väst,390,199,269,477
Leila,Norr,228,153,263,198
Hassan,Öst,228,496,195,162
Fatima,Väst,153,221,297,322
Ali,Syd,489,184,194,223
Linh,Öst,138,303,356,182
Egon,Syd,344,424,469,327
Carlos,Öst,373,362,278,248
Yuki,Öst,435,147,392,309
Sofia,Norr,488,227,404,150
Diane,Öst,205,231,449,370
Anna,Väst,142,456,487,141
Nadir,Syd,131,280,198,158
Peter,Syd,476,434,142,293
Sunita,Syd,357,243,468,136

6.4 Matplotlib och Pyplot

Matplotlib är ett av de mest populära Python-biblioteken för att skapa högkvalitativa diagram och grafer. Det är mycket flexibelt och kan användas för att generera en mängd olika plottar och visuella datarepresentationer.

Pyplot är en modul i Matplotlib som förenklar gränssnittet genom att erbjuda en funktionell stil som liknar MATLAB. Pyplot ger en enkel sätt att generera grafer med hjälp av kommandon som påverkar en figur eller ett diagram på ett tillståndsfullt sätt. Med andra ord, Pyplot håller koll på det nuvarande diagrammet du jobbar med, och de funktioner du anropar påverkar det diagrammet.

6.4.1 Grundläggande komponenter

  1. Figurer och axlar: I Matplotlib är en "figur" hela fönstret eller sidan där saker ritas. Inom varje figur kan du ha en eller flera "axlar" (plottar). En axel är vad vi ofta tänker på som en "plot" – det har axlar och kan innehålla olika linjer eller markörer.
  2. Plotfunktioner: Pyplot tillhandahåller flera funktioner för att skapa olika typer av plottar:
    • plot(): Används för linjediagram.
    • scatter(): Används för scatter-plottar.
    • bar(): Används för vertikala stapeldiagram.
    • barh(): Används för horisontella stapeldiagram.
    • hist(): Används för histogram.
    • pie(): Används för pajdiagram.
  3. Anpassning: Du kan anpassa flera delar av dina diagram, från färgscheman till fonter, linjestilar, legendpositioner och mycket mer. Detta görs genom att ställa in egenskaper på figurer, axlar, och de enskilda plottarna.

6.4.2 Exempelsamling

Som vanligt när vi arbetar med olika paket så måste det först installeras innan vi kan använda paketet. Dokumentationen till Matplotlib kan vara bra att ha nära till hands ifall du vill använda fler funktioner än vad som visas här nedan i exemplen.

6.4.2.1 Ett enkelt linjediagram

Kodexempel

# matplotlib.pyplot används för att skapa figurer och axlar i plotter
import matplotlib.pyplot as plt
import numpy as np

# Exempeldata
x = np.arange(1, 6)                   # Skapar en array med värdena 1 till 5
y = np.random.randint(1, 20, size=5)  # Skapar en array med 5 slumpmässiga heltal mellan 1 och 19

# Ritar ut linjediagram
# Plottar x mot y, markerar datapunkter med cirklar (o),
# sätter färgen till blå (b), och ger serien etiketten 'Linje'
plt.plot(x, y, marker='o', color='b', label='Linje')

# Konfigurera diagrammet
plt.xlabel('X-axel')  # Sätter etikett för x-axeln
plt.ylabel('Y-axel')  # Sätter etikett för y-axeln
plt.title('Enkelt Linjediagram')  # Sätter en titel på diagrammet

# Ställer in så att x-axelns endast inkluderar de värden som finn i arrayen x
# plt.xticks(x)

# Lägger till en legend för att identifiera serier ('Linje'),
plt.legend()

# Visar figuren, detta steg är nödvändigt för att få diagrammet att renderas
plt.show()

Utskrift

6.4.2.2 Ett enkelt stapeldiagram

Kodexempel

import matplotlib.pyplot as plt
import numpy as np

# Exempeldata
x = np.arange(1, 6)
y = np.random.randint(1, 20, size=5)

plt.bar(x, y, color='r', label='Staplar')
plt.xlabel('X-axel')
plt.ylabel('Y-axel')
plt.title('Stapeldiagram')
plt.legend()
plt.show()

Utskrift

6.4.2.3 Kombinera flera figurer i samma diagram

Kodexempel

import matplotlib.pyplot as plt
import numpy as np

# Exempeldata
x = np.arange(1, 6)  # Skapa en array med sekventiella värden från 1 till 5, vilket representerar x-axeln.
y = np.random.randint(1, 20, size=5)  # Skapa slumpmässiga y-värden mellan 1 och 20 för stapeldiagrammet.
z = np.random.randint(1, 40, size=5)  # Skapa slumpmässiga y-värden mellan 1 och 40 för linjediagrammet.

# Skapa en figur och en axelinstans
# 'fig' representerar hela figuren eller fönstret. 'ax1' är axeln för stapeldiagrammet.
fig, ax1 = plt.subplots()

# Skapa stapeldiagram
ax1.bar(x, y, color='g', label='Staplar')  # Plotta stapeldiagram på ax1 med x som x-axel och y som höjd för staplarna.
ax1.set_xlabel('X-axel')  # Sätt etikett för x-axeln.
ax1.set_ylabel('Stapelvärden', color='g')  # Sätt etikett för y-axeln på ax1 och matcha färgen med staplarna.
ax1.tick_params(axis='y', labelcolor='g')  # Anpassa färgen på ax1's tick-märken och etiketter till grönt.

# Skapa en ny axel för linjediagrammet
ax2 = ax1.twinx()  # Skapa en ny axel som delar samma x-axel som ax1 men med en egen y-axel på höger sida.
ax2.plot(x, z, color='c', label='Linje')  # Plotta linjediagram på ax2 med x som x-axel och z som y-värden.
ax2.set_ylabel('Linjevärden', color='c')  # Sätt etikett för y-axeln på ax2 och matcha färgen med linjen.
ax2.tick_params(axis='y', labelcolor='c')  # Anpassa färgen på ax2's tick-märken och etiketter till cyan.

# Titel och visning
plt.title('Kombinerat Stapel- och Linjediagram')  # Sätt titeln på diagrammet.
fig.tight_layout()  # Justera layouten för att se till att allt får plats och ser bra ut.
plt.show()  # Visa diagrammet.

Utskrift

6.4.2.4 Rita diagram med data från Pandas

Kodexempel

import matplotlib.pyplot as plt
import pandas as pd
import numpy as np

# Skapar data för x- och y-axlarna
x = np.arange(1, 6)  # Skapar en array med sekventiella tal från 1 till 5
y = np.random.randint(1, 20, size=5)  # Genererar 5 slumpmässiga heltal mellan 1 och 19

# Skapar en DataFrame från tidigare genererad data
data = {'X': x, 'Y': y}
df = pd.DataFrame(data)

# Skriver ut DataFrame för att visa datan som kommer användas i plottningen
print(df)

# Initiates a new figure in matplotlib
plt.figure()  # Skapar en ny figur där diagrammet kommer att ritas

# Plottar data från DataFrame
# Här plottar vi kolumn 'X' som x-axel och 'Y' som y-axel
plt.plot(df['X'], df['Y'], label='Från DataFrame')  # Plot-kommandot använder kolumn 'X' som x-värden och 'Y' som y-värden

# Konfigurerar diagrammets titel och axlar
plt.title('Diagram från DataFrame')  # Sätter titeln på diagrammet
plt.xlabel('X')  # Namnger x-axeln
plt.ylabel('Y')  # Namnger y-axeln

# Lägger till en legend
plt.legend()  # Visar en förklaring vilket gör det lättare att identifiera serien i diagrammet

# Visar diagrammet
plt.show()  # Ritar upp och visar det färdiga diagrammet

Utskrift

Uppgift: m06u05

I exempel 6.3.2.2 Grundläggande beräkningar, sorteringar och filtreringar så läste vi in fem elevers resultat på tre olika prov. Denna informationen lagrades i ett DataFrame och sedan beräknade vi totalsumman för varje elev. Se till att du har ett DataFrame med namn, resultat på de tre delproven och sedan det totala resultatet för varje elev.

Uppgiften är nu att skapa ett stapeldiagram med följande inställningar;

  1. Staplarna skall vara blå.
  2. På x-axeln skall elevernas namn stå.
  3. Y-axeln skall vara mellan 0 och 30. Helst heltal, steglängden kan du få välja själv om du vill.
  4. Legend skall visa "Totalt resultat på provet"
  5. Diagrammets rubrik skall vara "Provresultat NP Ma01a", x-axelns text skall vara "Elever", y-axelns text skall vara "Provresultat".

En liten kluring är att rita ut ett streck i valfri färg som representerar medelvärdet för samtliga elever. TIPS: Om du inte vill skapa en linje som lagras i DataFrame så går det att använda axhline för att skapa en linje genom hela figuren.

Lös uppgiften steg för steg, kanske blir inte lösningen exakt som jag har beställt men då är det bättre att komma så nära som möjligt. Det kommer finnas ett lösningsförslag från mig tids nog och sedan kommer vi jobba vidare med detta exememplet och vidareutveckla det.

Exempel på hur utskriften kan se ut [klicka för att visa]

6.4.2.5 Labels

Kodexempel

import matplotlib.pyplot as plt
import pandas as pd

# Läs in data från en CSV-fil
df = pd.read_csv('prov03.csv', delimiter=';', header=None, names=['Namn', 'Prov1', 'Prov2', 'Prov3'])

# Beräkna totalpoäng för varje elev och lägg till denna data som en ny kolumn i DataFrame
df['Totalt'] = df[['Prov1', 'Prov2', 'Prov3']].sum(axis=1)

# Skapa ett stapeldiagram från DataFrame
# Varje elevs namn på x-axeln och deras totalpoäng på y-axeln
bars = plt.bar(df['Namn'], df['Totalt'], color='b', label='Totalpoäng')

# Lägg till text ovanför varje stapel för att visa poäng
# Använder en for-loop för att gå igenom varje 'bar' i diagrammet
for bar in bars:
    yval = bar.get_height()  # Hämta höjden av stapeln (totalpoängen)
    # Använd plt.text för att placera texten ovanför varje stapel
    plt.text(bar.get_x() + bar.get_width()/2, yval, round(yval, 1), ha='center', va='bottom')

# Ange etiketter och titlar för diagrammet för att förbättra dess läsbarhet och ge kontext
plt.xlabel('Namn')                      # Namn på eleverna på x-axeln
plt.ylabel('Totalpoäng')                # Poäng på y-axeln
plt.title('Stapeldiagram med Värden')   # Titel på diagrammet

# Lägg till en legend för att förklara vad 'blå' staplar representerar
plt.legend()

# Visa diagrammet
plt.show()

Utskrift

6.4.2.6 Staplade staplar

Kodexempel

# Importera nödvändiga bibliotek
import matplotlib.pyplot as plt
import pandas as pd

# Läs in data från en CSV-fil
df = pd.read_csv('prov03.csv', delimiter=';', header=None,
                 names=['Namn', 'Prov1', 'Prov2', 'Prov3'])

# Beräkna totalpoäng för varje elev genom att summera poängen från de tre proven
df['Totalt'] = df[['Prov1', 'Prov2', 'Prov3']].sum(axis=1)

# Skapa ett staplat stapeldiagram
# Vi använder plt.bar för att skapa individuella staplar för varje provresultat för varje elev
plt.bar(df['Namn'], df['Prov1'], color='b', label='Prov1')  # Första lagret med Prov1 resultat
plt.bar(df['Namn'], df['Prov2'], bottom=df['Prov1'], color='g', label='Prov2')  # Andra lagret ovanpå det första
plt.bar(df['Namn'], df['Prov3'], bottom=df['Prov1'] + df['Prov2'], color='r', label='Prov3')  # Tredje lagret ovanpå de två första

# Sätt etiketter och titel på diagrammet för att förtydliga vad som visas
plt.xlabel('Namn')  # Namnetikett för x-axeln
plt.ylabel('Totalpoäng')  # Poängetikett för y-axeln
plt.title('Stapeldiagram över provresultat')  # Titel på diagrammet

# Lägg till en legend för att förklara färgkodningen av de olika proven
plt.legend()

# Visa diagrammet
plt.show()

Utskrift

6.4.2.7 Grupperade staplar

Kodexempel

import matplotlib.pyplot as plt
import pandas as pd
import numpy as np

# Läs in data från en CSV-fil, ange att det inte finns någon header och definiera kolumnnamnen
df = pd.read_csv('prov03.csv', delimiter=';', header=None,
                 names=['Namn', 'Prov1', 'Prov2', 'Prov3'])

# Skapa en figur och en axel för att rita upp diagrammet
fig, ax = plt.subplots()

# Räkna antalet elever (rader i DataFrame)
n = len(df)

# Skapa en array med positioner för varje grupp av staplar, en position per elev
ind = np.arange(n)  # X-positioner för grupper, en per elev
width = 0.25  # Bredden på varje stapel

# Rita ut staplarna för varje prov
ax.bar(ind - width, df['Prov1'], width, label='Prov1', color='b')  # Staplar för Prov1, placerade till vänster
ax.bar(ind, df['Prov2'], width, label='Prov2', color='g')  # Staplar för Prov2, i mitten
ax.bar(ind + width, df['Prov3'], width, label='Prov3', color='r')  # Staplar för Prov3, placerade till höger

# Konfigurera x-axeln
ax.set_xlabel('Namn')  # Sätt etikett för x-axeln till "Namn"
ax.set_xticks(ind)  # Sätt positionerna för tick-märkena på x-axeln
ax.set_xticklabels(df['Namn'])  # Sätt etiketter för tick-märkena på x-axeln till elevernas namn

# Konfigurera y-axeln
ax.set_ylabel('Poäng')  # Sätt etikett för y-axeln till "Poäng"

# Sätt titel på diagrammet
ax.set_title('Grupperade stapeldiagram per Elev')  # Titel på diagrammet

# Lägg till en legend
ax.legend()  # Visar en legend som förklarar färgkodningen för de olika proven

# Visa diagrammet
plt.show()  # Ritar upp och visar det färdiga diagrammet

Utskrift

Uppgift: m06u06

I uppgift m06u04 så gjorde vi ett antal beräkningar på försäljningsstatistiken för ALS Systemsälj AB. Du skall nu få redovisa några av beräkningar i diagram.

  1. Rita ut total försäljning för samtliga försäljare under året, sortera denna i fallande ordning innan den skrivs ut. Säljarens namn på x-.axeln, label på varje stapel om du vill.
    1. Kan du vända på diagrammet så att staplarna är horisontella? barh() är nyckeln för detta.
  2. Summera total försäljning per kontor för att se vilket kontor som presterar bäst. Visa med kontorets namn som namn på x-axeln och med total försäljning som label på varje stapel.
    1. Om du kan dela upp den totala försäljningen med staplar för varje kvartal som staplas på varandra så gör gärna det.
  3. Finns det något mer du skulle vilja visa utifrån de beräkningar du har gjort, testa att leka med egenskapade diagram.

Här kommer några sista kodexempel som jag vill visa som inspiration.

6.4.2.8 Flera diagram i en figur & spara diagram som fil

Här kommer ett exempel på hur man kan skapa flera diagram i samma figur samt hur man också kan spara ner sitt diagram som en bildfil.

Kodexempel

import matplotlib.pyplot as plt
import numpy as np

# Skapa x- och y-koordinater
x = np.linspace(0, 10, 50)
y = np.sin(x)

# Skapa en figur och två subplots (1 rad, 2 kolumner)
fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(10, 4))

# Skapa ett linjediagram på den första axeln (ax1)
ax1.plot(x, y, 'b-o')           # 'b-o' specifierar blå färg och cirkelmarkörer
ax1.set_title('Linjediagram')   # Titel för första subplot
ax1.set_xlabel('x')             # Etikett för x-axeln
ax1.set_ylabel('sin(x)')        # Etikett för y-axeln

# Skapa ett stapeldiagram på den andra axeln (ax2)
ax2.bar(x, y, color='green')
ax2.set_title('Stapeldiagram')  # Titel för andra subplot
ax2.set_xlabel('x')             # Etikett för x-axeln
ax2.set_ylabel('sin(x)')        # Etikett för y-axeln

# Lägg till en övergripande titel för figuren
fig.suptitle('Jämförelse av Linje- och Stapeldiagram', fontsize=16)

# Visa diagrammen
plt.tight_layout()              # Justera layout för att förhindra överlappning
plt.savefig('subplots.png')     # Sparar den aktuella figuren till en fil
plt.show()                      # Visa upp diagrammet

Utskrift

6.4.2.9 Animation

Här följer ett favoritexempel med tärningar som simulerar yatzyslag och hur ett fåtal undersökningar påverkar en statistisk undersökning.

Kodexempel

import numpy as np
import matplotlib.pyplot as plt
from matplotlib.animation import FuncAnimation


# Funktion som simulerar en omgång av Yatzy-kast. Den utför 'rolls_per_round' antal kast.
def simulate_yatzy_round(rolls_per_round):
    # Skapa en matris där varje rad representerar fem tärningskast.
    rolls = np.random.randint(1, 7, (rolls_per_round, 5))
    yatzy_count = 0  # Initiera räknaren för antalet yatzy.

    # Kontrollera varje kast för att se om alla tärningar visar samma nummer.
    for roll in rolls:
        # np.unique returnerar alla unika värden i kastet. Om längden är 1, är alla värden lika.
        if len(np.unique(roll)) == 1:
            yatzy_count += 1
    return yatzy_count


# Uppdateringsfunktion för animeringen som kallas för varje ny frame i animationen.
def update(frame):
    # Nollställ plottningen för första framen och sätt upp diagraminställningarna.
    if frame == 0:
        ax.clear()
        ax.set_xlim(0, num_rounds)
        ax.set_ylim(0, 30)  # Sätt y-axelns intervall baserat på förväntade värden.
        ax.set_title("Yatzy-simulation")
        ax.set_xlabel("Omgång")
        ax.set_ylabel("Antal Yatzies")
        ax.axhline(y=expected_yatzies, color='green', linestyle='dashed', linewidth=1, label='Förväntat antal Yatzies')

    # Simulera en omgång av Yatzy och uppdatera datamatriserna.
    yatzy_count = simulate_yatzy_round(rolls_per_round)
    results[frame] = yatzy_count
    cumulative_averages[frame] = np.mean(results[:frame + 1])

    # Rita upp resultaten för aktuell frame.
    ax.plot(results[:frame + 1], 'bo', label='Yatzies denna omgång' if frame == 0 else "")
    ax.plot(cumulative_averages[:frame + 1], 'r-', label='Kumulativt genomsnitt' if frame == 0 else "")
    # Visa legenden endast i den första framen för att undvika att den upprepas.
    if frame == 0:
        ax.legend()


# Definiera antal omgångar och antal kast per omgång.
num_rounds = 100
rolls_per_round = 15000

# Beräkna det förväntade antalet Yatzies baserat på sannolikheten för att alla fem tärningar visar samma siffra.
expected_yatzies = rolls_per_round * (6 / 7776)  # 6 möjliga utfall (1-6), 7776 totala utfall för 5 tärningar.

# Initiera datalagring för resultat och kumulativa genomsnitt.
results = np.zeros(num_rounds)
cumulative_averages = np.zeros(num_rounds)

# Skapa figur och axel för plottningen.
fig, ax = plt.subplots()

# Lägg till den gröna linjen som visar det förväntade antalet Yatzies.
ax.axhline(y=expected_yatzies, color='green', linestyle='dashed', linewidth=1, label='Förväntat antal Yatzies')

# Starta animeringen som uppdaterar plotten för varje ny frame.
ani = FuncAnimation(fig, update, frames=num_rounds, repeat=False)

# Visa den färdiga grafen.
plt.show()

Utskrift