ebSkola

6.3 Datu transformācija

Stundas uzdevums: Pārvērst vienkāršu sarakstu par "viedo karti". Kad mēs ielādējam datus no CSV, tie bieži ir "netīri" (ar liekām atstarpēm vai tikai teksta formātā). Apgūsi, kā notīrīt datus un transformēt tos, izveidojot vārdnīcu, kurā lokācijas ID nodrošina acumirklīgu piekļuvi visai istabas informācijai.

SR 2.4.14. (Datu apstrāde un validācija)

70 min plāns: Teorija un paraugs (~10 min) · 1. uzdevums (~15 min) - notīri datus ar strip un int · 2. uzdevums (~25 min) - pārvērs CSV rindas par vārdnīcu pēc id · 3. uzdevums (~20 min) - salīdzini meklēšanu sarakstā un vārdnīcā. Papildu uzdevumu sāc tikai tad, ja pārējie trīs ir gatavi.

Pirms sāc: atver savu pasaule.csv no 6.2 stundas un VS Code. Šoreiz datus ne tikai nolasīsi, bet arī pārkārtosi.

Teorija: No Saraksta uz Vārdnīcu

Kad mēs nolasām CSV ar csv.DictReader, mēs iegūstam rindu sarakstu. Lai tajā atrastu 50. lokāciju, datoram ir jāpārskata 49 iepriekšējās. Transformējot datus lielā vārdnīcā, mēs iegūstam tūlītēju piekļuvi pēc atslēgas (ID).

Metode / Funkcija Ko tā dara? Kāpēc tas palīdz CSV apstrādē?
.strip() Noņem tukšās atstarpes no teksta sākuma un beigām. Izlabo Excel eksporta kļūdas (piem., " 1 " kļūst par "1").
int(teksts) Pārvērš tekstu par veselu skaitli. CSV visi dati ir teksts (str). Mums ID vajag kā skaitļus.
if atslēga in dict: Pārbauda, vai konkrētā atslēga eksistē vārdnīcā. Novērš programmas avarēšanu, ja spēlētājs izvēlas neesošu vietu.

Praktiskie uzdevumi

1. uzdevums -

Notīri datus ar strip un int

Beigās tavi dati būs tīri, arī ja tabulā iekļuvušas liekas atstarpes.

  1. Ieraksti izklājlapā vienam id lieku atstarpi, piemēram 2 , un eksportē CSV no jauna.
  2. Nolasi failu ar DictReader un izdrukā repr(rinda['id']).
  3. Pieraksti, vai izdrukā redzamas atstarpes.
  4. Pievieno rinda['id'].strip() un izdrukā vēlreiz.
  5. Pievieno int(rinda['id'].strip()) un izdrukā rezultāta tipu.
  6. Mēģini izsaukt int() bez strip() uz teksta ar burtu un pieraksti kļūdu.

Gatavs, kad: pēc strip() un int() izdrukājas <class 'int'> bez atstarpēm.

2. uzdevums -

Pārvērs CSV rindas par vārdnīcu pēc id

Beigās jebkuru lokāciju varēs atrast pēc tās numura uzreiz.

  1. Izveido tukšu vārdnīcu pasaules_karte = {}.
  2. Uzraksti ciklu, kas iet cauri DictReader rindām.
  3. Izrēķini katrā ciklā id_skaitlis = int(rinda['id'].strip()).
  4. Pievieno pasaules_karte[id_skaitlis] = rinda.
  5. Izdrukā pēc cikla pasaules_karte[2]['teksts'].
  6. Izdrukā lokāciju skaitu ar len().
  7. Palaid un pārbaudi, vai teksts sakrīt ar tabulu.

Gatavs, kad: vari izdrukāt otrās lokācijas tekstu vienā rindā, nenorādot nekādu ciklu.

3. uzdevums -

Salīdzini meklēšanu sarakstā un vārdnīcā

Beigās tu sapratīsi, kāpēc vārdnīca ir ātrāka par sarakstu.

  1. Uzraksti ciklu, kas sarakstā meklē lokāciju ar id 3 un skaita pārbaudes.
  2. Izdrukā, cik rindas cikls pārskatīja, pirms atrada.
  3. Izdrukā to pašu lokāciju no vārdnīcas pa tiešo.
  4. Pieraksti, cik pārbaužu vajadzēja katrā gadījumā.
  5. Iedomājies 50 lokācijas un pieraksti, cik pārbaužu būtu sarakstā.
  6. Pieraksti vienu secinājumu: kad saraksts ir labāks par vārdnīcu.

Gatavs, kad: sarakstā vajag pārskatīt vairākas rindas, bet vārdnīcā - nevienu, un tu vari to izskaidrot.

Papildu uzdevums - Pasargā no bojātas rindas

Ja pamatdarbs ir gatavs, neļauj vienai kļūdainai rindai apturēt visu ielādi.

  1. Ieraksti tabulā vienā id vietā burtus, piemēram abc, un eksportē CSV.
  2. Palaid savu ielādes kodu un pieraksti kļūdu.
  3. Ieliec konvertāciju try blokā.
  4. Pievieno except ValueError:, kas izdrukā brīdinājumu un turpina.
  5. Palaid vēlreiz un pārbaudi, ka pārējās lokācijas ielādējās.

Gatavs, kad: programma izlaiž bojāto rindu ar brīdinājumu, bet pārējās lokācijas ielādē.

Biežākās kļūdas datu tīrīšanā:

1. Reģistrjutība: Python atšķir 'id' no 'ID'. Pārliecinies, ka koda atslēgas precīzi sakrīt ar CSV galvenēm!
2. ValueError konvertējot tukšumu: Tu nevari izdarīt int(""). Vienmēr pārbaudi (if rinda['merkis'] != "":), pirms mēģini tekstu pārvērst par skaitli.
3. Lokālo mainīgo pazušana: Ja pasaules_karte = {} definēsi iekšpusē with open() blokam vai ciklā, tai būs grūti piekļūt no ārpuses vai tā pārrakstīsies katru reizi no jauna.

Koda piemērs

import csv

pasaules_karte = {}

with open('pasaule.csv', mode='r', encoding='utf-8') as f:
    lasitajs = csv.DictReader(f)
    
    for rinda in lasitajs:
        # Notīrām un konvertējam galveno ID
        id_skaitlis = int(rinda['id'].strip())
        
        # Pievienojam rindu vārdnīcai
        pasaules_karte[id_skaitlis] = rinda

# Tagad piekļuve jebkurai istabai ir acumirklīga:
# Izprintēsim 2. lokācijas nosaukumu un tekstu
istaba = pasaules_karte[2]
print(f"Tu atrodies: {istaba['nosaukums']}")
print(istaba['teksts'])
Transformācija pabeigta!
Tu atrodies: Vecais mežs
Koki šeit aug tik cieši...