Python for samfunnsøkonomi

Forelesningsnotater - Espen Sirnes

4 - lister, oppslag og numpy

En liste er en datastruktur, som igjen er en organisering av objekter. Slike datastrukturer er helt sentralt i alle programmeringsspråk, og alle språk har ulike typer strukturer til ulike formål. I noen datastrukturer kan du putte alle typer objekter sammen, slik som tekst, funksjoner og tall og nye datastrukturer.

I andre datastrukturer kan du kun putte tall. Slike datastrukturer er vanligvis det vi i matematikken kaller vektorer og matriser. Disse kommer vi tilbake til når vi skal snakke om Numpy.

Det vi skal se på først er de innebygde datastrukturene til Python. Alle de innebygde strukturene kan inneholde alle typer objekter, men de har noen viktige egenskaper som skiller dem:

  • list (liste): Hvert element har en bestemt plassering i listen, Tilgang fås ved å referere til plasseringen (indeksen) i form av et heltall int.
  • Tuple: Lik lister, men kan ikke forandres når den er skapt. Hovedsakelig til bruk i forbindelse med funksjoner.
  • dict(dictionary, oppslag): Elementene har ikke en bestemt plassering. Tilgang fås ved å referere til en nøkkel (vanligvis en streng str)

Vi starter med å se på lister.

Lister

Lister lages med klammeparenteser. Her er noen lister med navn, forkortelse (Ticker), aksjekurs, markedsverdi, PE og gjeldsgrad for noen aksjer på Oslo Børs. Tallene er fra 27. november 2020 (kilde https://tilon.uit.no).

PE er "Price/Earnings", som er forholdet mellom selskapenes inntjening og prisen. Gjeldsgrad er hvor stor andel av total kapital som er gjeld. Det som ikke er gjeld er egenkapital.

Eksempel 1:

In [1]:
equinor=['Statoil', 'EQNR', 167.554919090282, 376883380048.5, 6.14609823076753, 0.617893838660362]
dnb=['DNB', 'DNB', 164, 259169427140, 11.1121822724349, 0.914999939276725]
telenor=['Telenor', 'TEL', 148.737572948101, 227115017138.4, 13.0211568133471, 0.715300723576896]
marine_harvest=['Marine Harvest', 'MHG', 225.589705235372, 118004750966.2, 21.6878893009616, 0.440427599611273]
aker_bp=['Aker BP', 'AKERBP', 272.499264741749, 103712690592, 26.7636558040214, 0.722568840028356]
yara_international=['Yara International', 'YAR', 333.328922090651, 99481443032.4, 86.741957363663, 0.465057636887608]
gjensidige_forsikring=['Gjensidige Forsikring', 'GJF', 172.830508474576, 92125000000, 24.9404407385348, 0.847890127134592]

Vi kan nå få tilgang til listene ved å referere til plasseringen med klammeparentes. Om vi vil referere navnet til equinor, som ligger på plass 0, kan vi for eksempel skrive equinor[0] (første element er alltid på plass 0 i Python):

In [2]:
equinor[0]
Out[2]:
'Statoil'

Vi ser at navnet er feil, dette er det gamle navnet til Equinor. Dette kan vi enkelt endre ved å sette element 0 i equinor-listen lik 'Equinor':

Eksempel 2:

In [3]:
print(equinor)
equinor[0]='Equinor'
print(equinor)
['Statoil', 'EQNR', 167.554919090282, 376883380048.5, 6.14609823076753, 0.617893838660362]
['Equinor', 'EQNR', 167.554919090282, 376883380048.5, 6.14609823076753, 0.617893838660362]

Men vi kan legge hvilke som helst objekter inn i en liste, så vi kan også lage en liste av listene over.

Eksempel 3:

In [4]:
stocks=[equinor,dnb,telenor,marine_harvest,aker_bp,yara_international,gjensidige_forsikring]
stocks
Out[4]:
[['Equinor',
  'EQNR',
  167.554919090282,
  376883380048.5,
  6.14609823076753,
  0.617893838660362],
 ['DNB', 'DNB', 164, 259169427140, 11.1121822724349, 0.914999939276725],
 ['Telenor',
  'TEL',
  148.737572948101,
  227115017138.4,
  13.0211568133471,
  0.715300723576896],
 ['Marine Harvest',
  'MHG',
  225.589705235372,
  118004750966.2,
  21.6878893009616,
  0.440427599611273],
 ['Aker BP',
  'AKERBP',
  272.499264741749,
  103712690592,
  26.7636558040214,
  0.722568840028356],
 ['Yara International',
  'YAR',
  333.328922090651,
  99481443032.4,
  86.741957363663,
  0.465057636887608],
 ['Gjensidige Forsikring',
  'GJF',
  172.830508474576,
  92125000000,
  24.9404407385348,
  0.847890127134592]]

Aker BP-aksjen er element nummer fem i denne listen. Om vi nå skal referere til den, så bruker vi indeks 4, siden vi starter på null.

Eksempel 4:

In [5]:
stocks[4]
Out[5]:
['Aker BP',
 'AKERBP',
 272.499264741749,
 103712690592,
 26.7636558040214,
 0.722568840028356]

Om du vil referere til siste element, bruker du indeks -1. Vil du referere til nest siste, bruker du indeks -2, og så videre:

Eksempel 5:

In [6]:
print(stocks[-1])
print(stocks[-2])
['Gjensidige Forsikring', 'GJF', 172.830508474576, 92125000000, 24.9404407385348, 0.847890127134592]
['Yara International', 'YAR', 333.328922090651, 99481443032.4, 86.741957363663, 0.465057636887608]

Du kan også referere til flere elementer som står ved siden av hverandre med en såkalt slice, eller skjære som vi kan kalle det på norsk:

Eksempel 6:

In [7]:
#Fra element to til og med tre:
stocks[2:4]
Out[7]:
[['Telenor',
  'TEL',
  148.737572948101,
  227115017138.4,
  13.0211568133471,
  0.715300723576896],
 ['Marine Harvest',
  'MHG',
  225.589705235372,
  118004750966.2,
  21.6878893009616,
  0.440427599611273]]
In [8]:
#Fra og med nest siste element:
stocks[-2:]
Out[8]:
[['Yara International',
  'YAR',
  333.328922090651,
  99481443032.4,
  86.741957363663,
  0.465057636887608],
 ['Gjensidige Forsikring',
  'GJF',
  172.830508474576,
  92125000000,
  24.9404407385348,
  0.847890127134592]]
In [9]:
#Til og med nest siste element:
stocks[:-1]
Out[9]:
[['Equinor',
  'EQNR',
  167.554919090282,
  376883380048.5,
  6.14609823076753,
  0.617893838660362],
 ['DNB', 'DNB', 164, 259169427140, 11.1121822724349, 0.914999939276725],
 ['Telenor',
  'TEL',
  148.737572948101,
  227115017138.4,
  13.0211568133471,
  0.715300723576896],
 ['Marine Harvest',
  'MHG',
  225.589705235372,
  118004750966.2,
  21.6878893009616,
  0.440427599611273],
 ['Aker BP',
  'AKERBP',
  272.499264741749,
  103712690592,
  26.7636558040214,
  0.722568840028356],
 ['Yara International',
  'YAR',
  333.328922090651,
  99481443032.4,
  86.741957363663,
  0.465057636887608]]

Og vi kan referere til en liste inne i en liste:

Eksempel 7:

In [10]:
print(f"Det tredje selskapet er {stocks[2][0]}")
Det tredje selskapet er Telenor

Det tredje selskapet, altså Equinor, har indeks to, siden Python starter indekseringen på 0.

Det er enkelt å utvide lister, vi bruker bare +. Om vi for eksempel vil legge til selskapet ['Tomra Systems', 'TOM', 276.409619134278, 41208789715.2, 52.8996016883184, 0.454299114121939], kan vi gjøre det slik:

Eksempel 8:

In [11]:
tomra_systems=['Tomra Systems', 'TOM', 276.409619134278, 41208789715.2, 52.8996016883184, 0.454299114121939]
stocks=stocks+[tomra_systems]
stocks
Out[11]:
[['Equinor',
  'EQNR',
  167.554919090282,
  376883380048.5,
  6.14609823076753,
  0.617893838660362],
 ['DNB', 'DNB', 164, 259169427140, 11.1121822724349, 0.914999939276725],
 ['Telenor',
  'TEL',
  148.737572948101,
  227115017138.4,
  13.0211568133471,
  0.715300723576896],
 ['Marine Harvest',
  'MHG',
  225.589705235372,
  118004750966.2,
  21.6878893009616,
  0.440427599611273],
 ['Aker BP',
  'AKERBP',
  272.499264741749,
  103712690592,
  26.7636558040214,
  0.722568840028356],
 ['Yara International',
  'YAR',
  333.328922090651,
  99481443032.4,
  86.741957363663,
  0.465057636887608],
 ['Gjensidige Forsikring',
  'GJF',
  172.830508474576,
  92125000000,
  24.9404407385348,
  0.847890127134592],
 ['Tomra Systems',
  'TOM',
  276.409619134278,
  41208789715.2,
  52.8996016883184,
  0.454299114121939]]

Unngå uønsket endring av objekter

En veldig vanlig nybegynnerfeil i Python er å glemme at selv om et objekt, slik som en liste, har fått nytt navn, så er det fortsatt det samme objektet. Dette er spesielt lett å glemme når du objektet er et argument i en funksjon. Her er for eksempel en funksjon som opererer på argumentet:

Eksempel 9:

In [12]:
#This function removes element i
def pop_and_print(a,i):
    last_element=a.pop(-1)
    print(last_element)
    
pop_and_print(stocks,-1)
stocks
['Tomra Systems', 'TOM', 276.409619134278, 41208789715.2, 52.8996016883184, 0.454299114121939]
Out[12]:
[['Equinor',
  'EQNR',
  167.554919090282,
  376883380048.5,
  6.14609823076753,
  0.617893838660362],
 ['DNB', 'DNB', 164, 259169427140, 11.1121822724349, 0.914999939276725],
 ['Telenor',
  'TEL',
  148.737572948101,
  227115017138.4,
  13.0211568133471,
  0.715300723576896],
 ['Marine Harvest',
  'MHG',
  225.589705235372,
  118004750966.2,
  21.6878893009616,
  0.440427599611273],
 ['Aker BP',
  'AKERBP',
  272.499264741749,
  103712690592,
  26.7636558040214,
  0.722568840028356],
 ['Yara International',
  'YAR',
  333.328922090651,
  99481443032.4,
  86.741957363663,
  0.465057636887608],
 ['Gjensidige Forsikring',
  'GJF',
  172.830508474576,
  92125000000,
  24.9404407385348,
  0.847890127134592]]

Over brukes pop-metoden til listeobjektet. En "metode" er en funksjon som kan henges på et bestemt objekt. Liste-objektet har altså en metode pop, som vi kan henge på listeobjektet med et punktum. pop-metoden fjerner elementet angitt av argumentet (siste element -1 i eksemplet under), og returnerer det fjernede elementet.

Kjører du koden over mange nok ganger, vil du se at alle elementene til slutt er borte og du får feilmelding.

Av og til vil du at funksjonen skal operere på argumentet, men om det ikke er meningen at argumentet skal være endret når funksjonen er ferdigkjørt, så kan du ta en kopi inne i funksjonen. Det gjøres enklest ved å bruke typen til objektet som funksjon. Du danner da et nytt objekt av samme type. For eksempel for en liste som stocksbruker du listsom funksjon

Eksempel 10:

In [13]:
#This function removes element i it
def pop_and_print(a,i):
    #making a copy:
    a=list(a)
    
    #doing the rest:
    last_element=a.pop(-1)
    print(last_element)
    
pop_and_print(stocks,-1)
stocks
['Gjensidige Forsikring', 'GJF', 172.830508474576, 92125000000, 24.9404407385348, 0.847890127134592]
Out[13]:
[['Equinor',
  'EQNR',
  167.554919090282,
  376883380048.5,
  6.14609823076753,
  0.617893838660362],
 ['DNB', 'DNB', 164, 259169427140, 11.1121822724349, 0.914999939276725],
 ['Telenor',
  'TEL',
  148.737572948101,
  227115017138.4,
  13.0211568133471,
  0.715300723576896],
 ['Marine Harvest',
  'MHG',
  225.589705235372,
  118004750966.2,
  21.6878893009616,
  0.440427599611273],
 ['Aker BP',
  'AKERBP',
  272.499264741749,
  103712690592,
  26.7636558040214,
  0.722568840028356],
 ['Yara International',
  'YAR',
  333.328922090651,
  99481443032.4,
  86.741957363663,
  0.465057636887608],
 ['Gjensidige Forsikring',
  'GJF',
  172.830508474576,
  92125000000,
  24.9404407385348,
  0.847890127134592]]

Denne koden kan kjøres så mange ganger du vil, uten at stocks endres

Automatisering

Én måte å lage lister på, er med en enkel løkke. DU definerer først listen, og så legger du til elementer:

Eksempel 11:

In [14]:
a = [] #Defining the list
for i in range(4):
    a.append(5*i + 20)
a
Out[14]:
[20, 25, 30, 35]

Alternativt kan vi bruke "list comprehension", som er en enklere måte å lage lister på, dersom operasjonen ikke er for komplisert:

Eksempel 12:

In [15]:
a = [5*i+20 for i in range(4)]
a
Out[15]:
[20, 25, 30, 35]

Tuple

En tuple fungerer ganske likt som en liste når du skal hente noe fra den. Men i motsetning til en liste, så går det ikke an å endre på en tuple etter at den er skapt. Du kan lage en tuple enten ved å bruke den innebygde funksjonen tuple() eller ved å lage en liste med en vanlig parentes:

Eksempel 13:

In [16]:
a=tuple(equinor)
b=('Equinor', 'EQNR', 146.85, 315357973561)
print(type(a))
print(type(b))
<class 'tuple'>
<class 'tuple'>

Vi kan få tak i innholdet, men det går ikke an å endre på innholdet i en tupleetter at den er skapt:

Eksempel 14:

In [18]:
print(a[0])
a[0]='Statoil'
Equinor
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
Cell In[18], line 2
      1 print(a[0])
----> 2 a[0]='Statoil'

TypeError: 'tuple' object does not support item assignment

Tuple er mest brukt i forbindelse med funksjoner, og er ikke noe vi kommer til å bruke mye tid på i dette kurset.

Numpy

Numpy er en pakke som kan gjøre matematiske beregninger på store datasett svært effektivt. En matrise er en liste der alle rader har like mangee elementer, og det er jo tilfelle med vår stocks-liste.

Vi starter med å definere en liste av liste med informasjon om aksjene:

Eksempel 15:

In [19]:
stocks=[
['Equinor', 'EQNR', 167.554919090282, 376883380048.5, 6.14609823076753, 0.617893838660362] , 
['DNB', 'DNB', 164, 259169427140, 11.1121822724349, 0.914999939276725] , 
['Telenor', 'TEL', 148.737572948101, 227115017138.4, 13.0211568133471, 0.715300723576896] , 
['Marine Harvest', 'MHG', 225.589705235372, 118004750966.2, 21.6878893009616, 0.440427599611273] , 
['Aker BP', 'AKERBP', 272.499264741749, 103712690592, 26.7636558040214, 0.722568840028356] , 
['Yara International', 'YAR', 333.328922090651, 99481443032.4, 86.741957363663, 0.465057636887608] , 
['Gjensidige Forsikring', 'GJF', 172.830508474576, 92125000000, 24.9404407385348, 0.847890127134592] , 
['Orkla', 'ORK', 86.5857852597003, 89087299091.2, 26.5615083754323, 0.350968405416214] , 
['Norsk Hydro', 'NHY', 31.4389402413895, 67532103728.64, 15.6215830970715, 0.439195576287418] , 
['SalMar', 'SALM', 449.3, 50905689550.7, 14.222545257898, 0.396134627028104] , 
['Tomra Systems', 'TOM', 276.409619134278, 41208789715.2, 52.8996016883184, 0.454299114121939] , 
['Aker', 'AKER', 514.200494811093, 40393931997, 43.4343354806452, 0.548092886866901] , 
]

Som du ser, så består listen av tolv rader og fire kolonner. Dette er altså en 12x6-matrise. Den kan enkelt konverteres til en numpy-matrise med funksjonen np.array() slik som her:

Eksempel 16:

In [20]:
import numpy as np
stocks_np=np.array(stocks)

Listen er nå lagret som en numpy 12x6-matrise i objektet stocks_np. Vi kan imidlertid ikke utføre noen matematiske beregninger slik denne matrisen står, fordi alle tall er i tekstformat. Som vi har sett tidligere går det bare an å regne med float, int og bool. At det er tekst ser vi ved at det er enkle anførselstegn ' rundt alle elementene.

Heldigvis er det veldig enkelt å hente ut informasjon fra numpy-matriser, fordi mulighetene til å skjære utsnitt er langt større enn for vanlige lister. Numpy-lister kan nemlig skjæres i flere dimensjoner.

I motsetning til vanlige lister, kan vi for eksempel velge ut kolonner. I en liste av lister velger du, som vi har sett, rad 2 og kolonne 0 med stocks[2][0]. Med numpy-matriser separerer du de to indeksene med et komma, stocks[2,0].

Men enda viktigere, du kan velge alle elementer ved å sette inn kolon : i stedet for tall. Dermed kan du velge hele kolonne 0 med stocks_np[:,0].

Her er vi mest interessert i de to siste kolonnene. Det er disse som inneholder tall. For å plukke ut disse velger vi alle radene (:) og alle kolonnene fra og med kolonne 2 (2:). Da får vi

Eksempel 17:

In [21]:
stocks_np[:,2:]
Out[21]:
array([['167.554919090282', '376883380048.5', '6.14609823076753',
        '0.617893838660362'],
       ['164', '259169427140', '11.1121822724349', '0.914999939276725'],
       ['148.737572948101', '227115017138.4', '13.0211568133471',
        '0.715300723576896'],
       ['225.589705235372', '118004750966.2', '21.6878893009616',
        '0.440427599611273'],
       ['272.499264741749', '103712690592', '26.7636558040214',
        '0.722568840028356'],
       ['333.328922090651', '99481443032.4', '86.741957363663',
        '0.465057636887608'],
       ['172.830508474576', '92125000000', '24.9404407385348',
        '0.847890127134592'],
       ['86.5857852597003', '89087299091.2', '26.5615083754323',
        '0.350968405416214'],
       ['31.4389402413895', '67532103728.64', '15.6215830970715',
        '0.439195576287418'],
       ['449.3', '50905689550.7', '14.222545257898', '0.396134627028104'],
       ['276.409619134278', '41208789715.2', '52.8996016883184',
        '0.454299114121939'],
       ['514.200494811093', '40393931997', '43.4343354806452',
        '0.548092886866901']], dtype='<U32')

Sist i matrisen over, står det dtype='<U21'. Det betyr at dette er tekstrenger på 21 eller færre tegn. Vi må imidlertid ha dette over i tallformat for å kunne jobbe med det. Det gjør vi slik:

Eksempel 18:

In [22]:
stocks_numbers=np.array(stocks_np[:,2:],dtype=float)
stocks_numbers
Out[22]:
array([[1.67554919e+02, 3.76883380e+11, 6.14609823e+00, 6.17893839e-01],
       [1.64000000e+02, 2.59169427e+11, 1.11121823e+01, 9.14999939e-01],
       [1.48737573e+02, 2.27115017e+11, 1.30211568e+01, 7.15300724e-01],
       [2.25589705e+02, 1.18004751e+11, 2.16878893e+01, 4.40427600e-01],
       [2.72499265e+02, 1.03712691e+11, 2.67636558e+01, 7.22568840e-01],
       [3.33328922e+02, 9.94814430e+10, 8.67419574e+01, 4.65057637e-01],
       [1.72830508e+02, 9.21250000e+10, 2.49404407e+01, 8.47890127e-01],
       [8.65857853e+01, 8.90872991e+10, 2.65615084e+01, 3.50968405e-01],
       [3.14389402e+01, 6.75321037e+10, 1.56215831e+01, 4.39195576e-01],
       [4.49300000e+02, 5.09056896e+10, 1.42225453e+01, 3.96134627e-01],
       [2.76409619e+02, 4.12087897e+10, 5.28996017e+01, 4.54299114e-01],
       [5.14200495e+02, 4.03939320e+10, 4.34343355e+01, 5.48092887e-01]])

Når vi konverterte listen til en ndarray, så brukte vi altså funksjonen np.array(), slik som i Eksempel 22. Men denne gangen legger vi til det valgfrie argument dtype=float for å eksplisitt gi beskjed om at vi ønsker strengene konvertert til flyttal.

Nå kan vi begynne å bruke tallene. For eksempel kan vi se grafisk om det er en sammenheng mellom gjeldsgrad og pris-inntjeningstraten (PE). Dette er de to siste kolonnene i datamatrisen:

Eksempel 19:

In [23]:
from matplotlib import pyplot as plt
fig,ax=plt.subplots()
ax.set_ylabel('PE')
ax.set_xlabel('gjeldsrate')
ax.scatter(stocks_numbers[:,-1], stocks_numbers[:,-2])
Out[23]:
<matplotlib.collections.PathCollection at 0x24b3a4f6310>

Ser du en sammenheng?

Det er også enkelt å regne med Numpy. Vi kan bruke alle de vanlige regneartene med numpy-matriser:

In [24]:
a=np.array([1,5,6,3])
b=np.array([23,15,2,10])

print(a+b)
print(a-b)
print(a*b)
print(a/b)
print(a**3)
print(a**0.5)#Kvadratroten
[24 20  8 13]
[-22 -10   4  -7]
[23 75 12 30]
[0.04347826 0.33333333 3.         0.3       ]
[  1 125 216  27]
[1.         2.23606798 2.44948974 1.73205081]

Oppslag

Et oppslag, eller dictionary har symbol dict i Python. Dette er en datastruktur der hvert element ikke identifiseres med hvor det er plassert, men med et nøkkelord (key). Å bruke oppslag i stedet for lister gjør ofte koden mer lesbar. Det finnes to måter å lage oppslag på; enten ved å bruke funksjonen dict():

Eksempel 20:

In [25]:
a=dict()
a['gjeldsrate']=stocks_numbers[:,-1]
a['PE']=stocks_numbers[:,-2]
print(type(a))
<class 'dict'>

Som vi ser, blir dette et objekt av type dict. Alternativt kan vi definere elementer inne i en krølleparentes på formen {nøkkel: objekt}, slik som dette:

In [26]:
b={
    'gjeldsrate':stocks_numbers[:,-1],
    'PE':stocks_numbers[:,-2], 
  }

print(type(b))
<class 'dict'>

Her er det altså to elementer med nøkler 'gjeldsrate' og 'PE', og tilhørende objekter fra stocks_numbers.

Vi legger merke til at dette også er en objekt av type dict. Med oppslag blir det enklere å bruke variablene, siden vi kan referere til dem med navn i stedet for indeks. Her er plottet i Eksempel 23 gjort med oppslag:

Eksempel 21:

In [27]:
plt.ylabel('PE')
plt.xlabel('gjeldsrate')
plt.scatter(a['gjeldsrate'], a['PE'])
Out[27]:
<matplotlib.collections.PathCollection at 0x24b3c7616d0>

Når du først har laget en dict, er det enkelt å legge til nye elementer. Det gjør du enkelt ved å bruke en nøkkel som ikke finnes, for eksempel 'Pris', og dette elementet lik ønsket objekt:

Eksempel 22:

In [28]:
a['Pris']=stocks_numbers[:,0]
plt.ylabel('Pris')
plt.xlabel('gjeldsrate')
plt.scatter(a['gjeldsrate'], a['Pris'])
Out[28]:
<matplotlib.collections.PathCollection at 0x24b3c776110>

dict-objektet er helt sentralt i selve byggeklossene til Python. Alle variabler du lager er faktisk elementer i to dict som du kan få frem med funksjonene locals() og globals(), som kaller de lokalt og globalt definerte variablene i miljøet du befinner deg. Dette eksemplet viser at objektet stocks som vi har definert i Eksempel 23, er identisk med elementet 'stocks' i locals().

Eksempel 23:

In [29]:
locals()['stocks']==stocks
Out[29]:
True

Vi ser at disse objektene egentlig er det samme, ved at den logiske testen om disse er like, returnerer sann (True).

Automatisering

Du kan automatisere å lage oppslag på samme måte som du kan automatisere lister. Med løkke kan du for eksempel gjøre slik:

Eksempel 24:

In [34]:
d = {}
for name, ticker, price, mcap, pe,debt in stocks:
    d[name] = [ticker, price, mcap, pe,debt]
d['Telenor']
Out[34]:
['TEL', 148.737572948101, 227115017138.4, 13.0211568133471, 0.715300723576896]

Men du kan også gjøre noe tilsvarende av "list comprehension":

Eksempel 25:

In [37]:
d = { name:[ticker, price, mcap, pe,debt] for name, ticker, price, mcap, pe,debt in stocks}
d['Telenor']
Out[37]:
['TEL', 148.737572948101, 227115017138.4, 13.0211568133471, 0.715300723576896]

Oppgaver

Det er enkelt å konvertere en pandas dataramme til numpy. Vi skal bruke skolegangeksemplet fra forelesning "3 - matplotlib". Vi henter inn dataene og konverterer dem til numpy slik:

In [1]:
import numpy as np
import pandas as pd
df=pd.read_csv('./data/schooling-gdp.csv')
schooling=np.array(df)
schooling
Out[1]:
array([['Norway', ' NOR', 73262.68, 11.65, 4886000],
       ['Kuwait', ' KWT', 67029.523, 6.39, 2992000],
       ['Luxembourg', ' LUX', 57882.809, 11.33, 508000],
       ['Switzerland', ' CHE', 55688.02, 12.92, 7809000],
       ['United States', ' USA', 49500.629, 13.24, 309011008],
       ['Ireland', ' IRL', 47823.504, 12.45, 4554000],
       ['Australia', ' AUS', 44854.902, 11.69, 22155000],
       ['Netherlands', ' NLD', 44004.145, 11.71, 16683000],
       ['Denmark', ' DNK', 43416.223, 11.97, 5555000],
       ['Hong Kong', ' HKG', 41687.949, 12.2, 6966000],
       ['Germany', ' DEU', 40627.23, 12.58, 80827000],
       ['Austria', ' AUT', 40489.809, 10.13, 8410000],
       ['Sweden', ' SWE', 40421.906, 11.95, 9390000],
       ['Canada', ' CAN', 40269.031, 12.74, 34148000],
       ['Finland', ' FIN', 38394.059, 10.71, 5366000],
       ['Belgium', ' BEL', 38177.945, 11.29, 10939000],
       ['Iceland', ' ISL', 37729.016, 11.48, 320000],
       ['Taiwan', ' TWN', 37188.895, 11.96, 23188000],
       ['Japan', ' JPN', 36595.633, 12.44, 128542000],
       ['France', ' FRA', 35786.16, 11.34, 62880000],
       ['United Kingdom', ' GBR', 34810.281, 12.46, 63460000],
       ['Italy', ' ITA', 34727.676, 10.71, 59325000],
       ['Spain', ' ESP', 31610.98, 10.75, 46931000],
       ['South Korea', ' KOR', 31589.705, 12.96, 49546000],
       ['New Zealand', ' NZL', 30867.053, 11.12, 4370000],
       ['Cyprus', ' CYP', 28046.375, 11.76, 1113000],
       ['Trinidad and Tobago', ' TTO', 27510.236, 10.96, 1328000],
       ['Czechia', ' CZE', 26129.568, 12.8, 10537000],
       ['Greece', ' GRC', 25815.799, 11.36, 10888000],
       ['Portugal', ' PRT', 25788.273, 8.71, 10596000],
       ['Malta', ' MLT', 22983.451, 11.06, 414000],
       ['Russia', ' RUS', 21754.066, 12.02, 143479008],
       ['Poland', ' POL', 21006.027, 11.62, 38330000],
       ['Hungary', ' HUN', 20477.799, 11.98, 9927000],
       ['Chile', ' CHL', 18092.941, 10.35, 17063000],
       ['Turkey', ' TUR', 17930.68, 7.44, 72327000],
       ['Malaysia', ' MYS', 17913.164, 10.89, 28208000],
       ['Iran', ' IRN', 17328.459, 9.15, 73763000],
       ['Romania', ' ROU', 16775.609, 11.08, 20472000],
       ['Venezuela', ' VEN', 16357.737, 8.78, 28440000],
       ['Argentina', ' ARG', 15841.659, 9.71, 40896000],
       ['Uruguay', ' URY', 15783.405, 8.61, 3359000],
       ['Mauritius', ' MUS', 15178.326, 9.44, 1248000],
       ['Panama', ' PAN', 15055.237, 9.72, 3643000],
       ['Bulgaria', ' BGR', 14906.785, 11.07, 7425000],
       ['Mexico', ' MEX', 14507.013, 9.18, 114093000],
       ['Barbados', ' BRB', 13995.613, 9.57, 282000],
       ['Brazil', ' BRA', 13541.462, 8.17, 195714000],
       ['Algeria', ' DZA', 12590.226, 7.0, 35977000],
       ['Thailand', ' THA', 12496.244, 8.47, 67195000],
       ['Serbia', ' SRB', 12453.482, 11.52, 8991000],
       ['Costa Rica', ' CRI', 12106.992, 8.43, 4577000],
       ['Dominican Republic', ' DOM', 11500.132, 8.12, 9695000],
       ['South Africa', ' ZAF', 11388.641, 9.89, 51217000],
       ['Tunisia', ' TUN', 10647.835, 8.0, 10635000],
       ['Colombia', ' COL', 10636.5, 9.35, 45223000],
       ['Albania', ' ALB', 9544.7402, 10.44, 2948000],
       ['Jordan', ' JOR', 9351.3877, 10.0, 7262000],
       ['Iraq', ' IRQ', 9344.5439, 7.43, 29742000],
       ['China', ' CHN', 9337.29, 8.25, 1368811008],
       ['Peru', ' PER', 9262.1641, 9.28, 29028000],
       ['Egypt', ' EGY', 9148.8398, 7.44, 82761000],
       ['Ecuador', ' ECU', 9129.1367, 8.02, 15011000],
       ['Sri Lanka', ' LKA', 8390.4297, 10.67, 20262000],
       ['Indonesia', ' IDN', 7365.4385, 8.02, 241834000],
       ['Belize', ' BLZ', 7145.9521, 9.63, 322000],
       ['Eswatini', ' SWZ', 7042.5239, 5.33, 1065000],
       ['Fiji', ' FJI', 6902.0688, 10.35, 860000],
       ['Paraguay', ' PRY', 6825.2051, 7.99, 6248000],
       ['Jamaica', ' JAM', 6675.1768, 10.33, 2810000],
       ['Morocco', ' MAR', 6421.9375, 5.27, 32343000],
       ['Guatemala', ' GTM', 6359.2627, 5.21, 14630000],
       ['El Salvador', ' SLV', 6096.9585, 8.06, 6184000],
       ['Syria', ' SYR', 5700.3291, 7.07, 21363000],
       ['Philippines', ' PHL', 5391.2339, 8.65, 93967000],
       ['Bolivia', ' BOL', 4806.6094, 8.57, 10049000],
       ['Yemen', ' YEM', 4553.5571, 3.84, 23155000],
       ['India', ' IND', 4357.0596, 6.59, 1234280960],
       ['Pakistan', ' PAK', 4171.4165, 5.19, 179424992],
       ['Nicaragua', ' NIC', 3992.762, 6.82, 5824000],
       ['Ghana', ' GHA', 3931.2917, 7.66, 24780000],
       ['Honduras', ' HND', 3789.9104, 6.6, 8317000],
       ['Sudan', ' SDN', 3608.7856, 3.49, 34545000],
       ['Myanmar', ' MMR', 3422.2415, 5.11, 50601000],
       ['Zambia', ' ZMB', 2870.8872, 7.4, 13606000],
       ['Senegal', ' SEN', 2741.1213, 3.11, 12678000],
       ['Cameroon', ' CMR', 2684.9727, 6.41, 20341000],
       ['Gambia', ' GMB', 2681.8586, 3.92, 1793000],
       ['Kenya', ' KEN', 2484.0349, 6.47, 42031000],
       ["Cote d'Ivoire", ' CIV', 2452.6096, 4.93, 20533000],
       ['Lesotho', ' LSO', 2432.7976, 6.08, 1996000],
       ['Bangladesh', ' BGD', 2411.1021, 6.22, 147575008],
       ['Cambodia', ' KHM', 2330.1272, 4.94, 14312000],
       ['Nepal', ' NPL', 1996.1962, 4.44, 27013000],
       ['Benin', ' BEN', 1919.9968, 4.57, 9199000],
       ['Mali', ' MLI', 1873.281, 2.14, 15049000],
       ['Uganda', ' UGA', 1723.5942, 5.87, 32428000],
       ['Haiti', ' HTI', 1650.2697, 5.17, 9949000],
       ['Zimbabwe', ' ZWE', 1479.0305, 7.86, 12698000],
       ['Togo', ' TGO', 1222.8151, 6.09, 6422000],
       ['Sierra Leone', ' SLE', 1161.8798, 4.28, 6416000],
       ['Malawi', ' MWI', 972.04572, 5.01, 14540000],
       ['Mozambique', ' MOZ', 969.23077, 2.03, 23532000],
       ['Niger', ' NER', 845.86932, 1.95, 16464000],
       ['Liberia', ' LBR', 786.67023, 4.35, 3891000],
       ['Democratic Republic of Congo', ' COD', 634.97137, 3.79,
        64564000]], dtype=object)
  1. Bytt ut navnet til "Ireland" med "Republic of Ireland" og "United States" med "United States of America"
In [ ]:
 
  1. Print data for "Luxembourg"
In [ ]:
 
  1. Print data for "Liberia" ved å referere til nest siste element.
In [ ]:
 
  1. Print BNP per capita for de tre siste elementene i schooling (ligger i kolonne med indeks 2)
In [ ]:
 
  1. Print BNP per capita for de tre siste elementene i schooling men hent kolonnen ved å refere til tredje siste kolonne.
In [ ]:
 
  1. Plukk ut de tre siste kolonnene i schooling, som representerer BNP per capita, skolegang og befolkning, og konverter dem til datatype float.
In [ ]:
 
  1. Lag et oppslag (dictionary) med de tre siste kolonnene og passende navn som nøkler. Kall det schooling_dict.
In [ ]:
 
  1. Lag en ny variabel i oppslaget med navn "Total schooling" som er produktet av skolegang og befolkning.
In [ ]:
 
  1. Lag en ny variabel "Total GDP" som er produktet av BNP per capita og befolkning.
In [ ]:
 
  1. Lag et scatterplot med de to variablene du nettopp lagde.
In [ ]:
 
  1. Lag plottet over, men konverter variablene med np.log()
In [ ]:
 
  1. Lag en ny variabel "GDP per schooling" som er BNP per capita delt på skolegang.
In [ ]:
 
  1. Lag et liggende stolpediagram med navn på land og "GDP per schooling". Du bruker da funksjonen plt.barh på denne måten:
    plt.barh(names,values)
    Hvor names er en liste med navnene og values er de tilhørende verdiene.
In [ ]:
 
  1. Dette blir ikke pent. Velg kun de 20 første landene, og forsøk på nytt.
In [ ]:
 
  1. med argsort får du rangeringen til etter en sortering. Her er rangeringen for "GDP per schooling"
In [ ]:
 

[::-1] til slutt sørger for å reversere sorteringen. Legg referansen til soreringen inn i variabelen sorted, og lag diagrammet på nytt med sorterte verdier. Om du har en numpy-liste a, kan du velge de sorterte verdiene med a[sorted]

Lag

a) et nytt diagram med alle landene og

In [ ]:
 

b) et diagram med de 20 øverste.

In [ ]:
 

c) et diagram med de 20 nederste

In [ ]: