Problem
- Jest to jeden z poważniejszych problemów
- 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
.xlsx
to plik binarny, łatwo czytany przez Excela czy LibreOffice Calc.csv
to plik tekstowy1 — również da się go otworzyć za pomocą aplikacji typu arkusz elektronicznyJego 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.
.json
(wym dżejson, z akcentem na pierwszą sylabę) JavaScript Object NotationTen 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
jest specjalna funkcja
xlsread()
, ale określona jest w dokumentacji jako niezalecana. Zamiast niej zaleca się użycie:Funkcja zwraca trzy tablice danych:
- numeryczne
- tekstowe
- 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.
Za jej zaletę można uznać umiejętność wczytania zakresu komórek.
Nie zalecam.
readtable()
>> A = readtable('owid-covid-data.csv');
>> size(A)
ans =
348596 67
- Wynik sensowny, tekst został przeczytany jako tekst, liczby jako liczby, daty jako obiekt zawierający datę
- Wszystkie elementy są typu cell array co nieco komplikuje manipulacje
- Wynik jest obiektem typu table, zalet możliwy jest dostęp do wartości przez nazwy kolumn
readmatrix()
- Czyta tylko wartości liczbowe z pliku
- Wartości tekstowe zamienia na NaN
- Nieużyteczne w tym przypadku
>> B = readmatrix('owid-covid-data.csv');
>> size(B)
ans =
348596 67
readcell()
DosyćNiewyobrażalnie długi (w porównaniu z poprzednimi poleceniami) czas wykonania2.Dane wczytywane są jako cell array
>> C = readcell('owid-covid-data.csv'); >> size(C) ans = 348597 67
Jak widać nagłówki kolumn zostały potraktowane jako dane.
JSON
Nie ma funkcji pozwalającej czytać pliki typu
.json
.Trzeba przeczytać cały plik w trybie tekstowym
a następnie
Jest funkcja
jsondecode()
, która rozkodowuje daneWszystko działa, ale danym nadawana jest postać drzewiasta i konwertowane są one na złożoną strukturę
Import Tool
- Jeżeli wskazać plik
.csv
w oknie Current Folder i dwukrotnie kliknąć — uruchamiane jest narzędzie Import Tool. - Narzędzie analizuje plik danych.
- Można poprosić o wygenerowanie skryptu (prostego programu) do importowania pliku.
- Używa funkcji
readtable()
do wczytania danych. - 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
- Wydaje się, że narzędzie Import Tool robi najlepszą robotę.
- W przypadku danych wyłącznie numerycznych
readmatrix()
może być również sensowne. - 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ę.
- Zaletą tabeli jest to, że pozwala używać symbolicznych nazw kolumn, co ułatwia życie.
Import danych z „przecinkiem dziesiętnym”
- 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)
Otwieram za pomocą Import Tool i zmieniam
Column delimiters
zcomma
nasemicolon
W okienku wszystko wygląda OK, ale wyświetlane wartości są trochę z kosmosu
Trzeba zmienić jeszcze
Delimiter options
(poniżej) zperiod
nacomma
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.
Wykorzystywana jest funkcja
readtable()
.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).