Import danych

Problem

  1. Jest to jeden z poważniejszych problemów
  2. MATLAB dostarcza sporo narzędzi do jego rozwiązania, ale…

Zacznijmy od przykładu.

  • jest serwis udostępniający dane o „sytuacji kowidowej” na świecie (Our World in Data).
  • dane dostępne są jako plik .csv lub .xlsx lub .json
  • wydaje się, że wczytanie tego do MATLABa powinno być prostym zadaniem

Typy plików

  1. .xlsx to plik binarny, łatwo czytany przez Excela czy LibreOffice Calc

  2. .csv to plik tekstowy1 — również da się go otworzyć za pomocą aplikacji typu arkusz elektroniczny

    Jego struktura jest prosta: pola zawierające dane oddzielane przecinkami, liczby i tekst zapisane „normalnie”, gdy pole zawiera przecinek — musi być wzięte w cudzysłowy; zazwyczaj pierwszy wiersz danych zawiera nazwy kolumn.

  3. .json (wym dżejson, z akcentem na pierwszą sylabę) JavaScript Object Notation

    Ten format (również tekstowy, ale trudny w odbiorze) opracowany został na potrzeby języka Javascrippt i jest dziś bardzo popularny, gdyż pozwala pracować z danymi posiadającymi wewnętrzną strukturę bogatszą niż tablica.

XLSX

  1. jest specjalna funkcja xlsread(), ale określona jest w dokumentacji jako niezalecana. Zamiast niej zaleca się użycie:

  2. Funkcja zwraca trzy tablice danych:

    1. numeryczne
    2. tekstowe
    3. surowe (raw)

    co wydaje się być sporym marnotrawstwem miejsca, tym bardziej, że kolumny całkowicie tekstowe podczas importu danych numerycznych są gubione; w pewnym sensie gubiona jest przez to cała struktura danych.

  3. Za jej zaletę można uznać umiejętność wczytania zakresu komórek.

  4. Nie zalecam.

readtable()

>> A = readtable('owid-covid-data.csv');
>> size(A)
ans =
      348596          67
  1. Wynik sensowny, tekst został przeczytany jako tekst, liczby jako liczby, daty jako obiekt zawierający datę
  2. Wszystkie elementy są typu cell array co nieco komplikuje manipulacje
  3. Wynik jest obiektem typu table, zalet możliwy jest dostęp do wartości przez nazwy kolumn

readmatrix()

  1. Czyta tylko wartości liczbowe z pliku
  2. Wartości tekstowe zamienia na NaN
  3. Nieużyteczne w tym przypadku
>> B = readmatrix('owid-covid-data.csv');
>> size(B)
ans =
      348596          67

readcell()

  1. Dosyć Niewyobrażalnie długi (w porównaniu z poprzednimi poleceniami) czas wykonania2.

  2. Dane wczytywane są jako cell array

    >> C = readcell('owid-covid-data.csv');
    >> size(C)
    ans =
          348597          67
    
  3. Jak widać nagłówki kolumn zostały potraktowane jako dane.

JSON

  1. Nie ma funkcji pozwalającej czytać pliki typu .json.

  2. Trzeba przeczytać cały plik w trybie tekstowym

    a następnie

  3. Jest funkcja jsondecode(), która rozkodowuje dane

  4. Wszystko działa, ale danym nadawana jest postać drzewiasta i konwertowane są one na złożoną strukturę

Import Tool

  1. Jeżeli wskazać plik .csv w oknie Current Folder i dwukrotnie kliknąć — uruchamiane jest narzędzie Import Tool.
  2. Narzędzie analizuje plik danych.
  3. Można poprosić o wygenerowanie skryptu (prostego programu) do importowania pliku.
  4. Używa funkcji readtable() do wczytania danych.
  5. Wynik jest zbliżony do „zwykłego” readtable(), ale pewne wartości zostały jednak potraktowane inaczej — jako kategorie.

Teraz wyszukiwanie jest proste:

rows = owidcoviddata.iso_code == 'POL';
Polska = owidcoviddata(rows,:);
>> size(Polska)
ans =
   594    65

Wnioski

  1. Wydaje się, że narzędzie Import Tool robi najlepszą robotę.
  2. W przypadku danych wyłącznie numerycznych readmatrix() może być również sensowne.
  3. Efekt Import Tool jest o tyle lepszy w tym przypadku, że narzędzie zauważa, że pewne dane mają charakter enumeratywny (są tekstowe, ale przyjmują skończoną, niewielką liczbę wartości) co pozwala nadać tabeli dodatkową strukturę.
  4. Zaletą tabeli jest to, że pozwala używać symbolicznych nazw kolumn, co ułatwia życie.

Import danych z „przecinkiem dziesiętnym”

  1. Mamy plik danych dane.csv z zawartością
A;B;C
0,408739936944977;5,31424724802927;51,8997918773948
0,243171449076818;7,75458612632023;84,9990492852384
0,342222195073958;9,9776580785975;12,0429481337952

(4 wiersze, trzy kolumny)

  1. Otwieram za pomocą Import Tool i zmieniam Column delimiters z comma na semicolon

  2. W okienku wszystko wygląda OK, ale wyświetlane wartości są trochę z kosmosu

  3. Trzeba zmienić jeszcze Delimiter options (poniżej) z period na comma

  4. Możemy też wybrać jak mają być zapamiętane dane (Output type):

    • Table (standardowo);
    • Column vectors (każda kolumna będzie importowana osobno jako zmienna o nazwie zgodnej z nazwą kolumny);
    • Numeric Matrix (tablica, ale tracimy informację o nazwach kolumn);
    • String Array (jako tekst);
    • Cell Array.
  5. Wykorzystywana jest funkcja readtable().

  6. Można życie sobie ułatwić za pomocą następującego triku:

    • użyjemy funkcji uigetfile() wykorzystującej graficzny interfejs pozwalający wskazć plik, który nas interesuje

      [F,P] = uigetfile('*.csv');
      

      funkcja zwraca wektor parametrów, pierwszym jest nazwa wskazanego pliku, drugim nazwa kartoteki, w której plik się znajduje

    • do importu danych użyjemy funkcji readtable()

      T = readtable(fullfile(P,F), 'Delimiter',';',
          'DecimalSeparator',',', 
          'VariableNamingRule','preserve')
      

      funkcja fullfile() składa z podanej kartoteki i nazwy pliku pełną jego nazwę;

    • dodatkowe parametry 'Delimiter',';' określają znak użyty jako separator wartości;

    • 'DecimalSeparator',',' — znak użyty jako separator dziesiętny;

    • 'VariableNamingRule','preserve' moemy użyć jeżeli chcemy aby MATLAB zachował nazwy kolumn nie konwertując ich (może to być niebezpieczne gdy zawierają odstępy).


  1. Czyli taki, który da się czytać. ↩︎

  2. O ile w poprzednich latach dało się go uruchamiać, to już w roku 2023 — nie! ↩︎

Poprzedni
Następny