FAQ czyli Czasami Zadawane Pytania

Mathematica

  1. W jaki sposób z tablicy wydobyć cały wiersz albo całą kolumnę?

    Niech mat będzie tablicą dwuwymiarową, utworzoną, na przykład poleceniem:

    mat = Table[Subscript[m, i, j], {i, 5}, {j, 5}];
    mat // MatrixForm
    
    $$\left( \begin{array}{ccccc} m_{1,1} & m_{1,2} & m_{1,3} & m_{1,4} & m_{1,5} \\ m_{2,1} & m_{2,2} & m_{2,3} & m_{2,4} & m_{2,5} \\ m_{3,1} & m_{3,2} & m_{3,3} & m_{3,4} & m_{3,5} \\ m_{4,1} & m_{4,2} & m_{4,3} & m_{4,4} & m_{4,5} \\ m_{5,1} & m_{5,2} & m_{5,3} & m_{5,4} & m_{5,5} \\ \end{array} \right)$$

    Aby dobrać się do wybranego elementu używamy funkcji Part:

    Part[mat, 1, 2]
    

    albo „skrótu" [[...]]

    mat[[1,2]]
    

    Aby wydobyć cały wiersz wystarczy użyć polecenia:

    mat[[4]]
    

    $\left\{m_{4,1},m_{4,2},m_{4,3},m_{4,4},m_{4,5}\right\}$ natomiast aby wydobyć kolumnę:

    mat[[All,4]]
    
    $\left\{m_{1,4},m_{2,4},m_{3,4},m_{4,4},m_{5,4}\right\}$

    Dodatkowo funkcja Span (której skrótem jest ;; pozwala wybrać dowolną „podtablicę" z tablicy:

    mat[[1 ;; 2, 3 ;; 5]]
    
    $$\left( \begin{array}{ccc} m_{1,3} & m_{1,4} & m_{1,5} \\ m_{2,3} & m_{2,4} & m_{2,5} \\ \end{array} \right)$$
  2. Jak utworzyć macierz o wymiarach $n\times m$, której zawartością są same zera?

    A = Table[0, {i, n}, {i, m}]
    
    $$\left( \begin{array}{cccc} 0 & 0 & 0 & 0 \\ 0 & 0 & 0 & 0 \\ 0 & 0 & 0 & 0 \\ \end{array} \right)$$
  3. W jaki sposób wstrzymać wypisywanie zawartości wyników obliczeń (na przykład tablic) na ekranie?

    Na końcu polecenia należy umieścić średnik (;).

  4. W jaki sposób dodać (usunąć) element listy?

    Służą do tego polecenia Append (dodaj na końcu), Prepend (dodaj na początku), Insert (wstaw), Riffle (wstaw między elementami listy), ReplacePart (zamień) Delete (usuń). Dobry tutorial jest tu w helpie Mathematici oraz na stronach WWW.

    Dodanie elementu $a$ na końcu listy $l$: Append[l,a]:

    Lista l ma trzy elementy

    l={1,2,3};
    

    a jeden element

    a=4;
    

    po wykonaniu polecenia

    l=Append[l,a];
    

    l ma wartość:

    {1,2,3,4}
    

    W szczególności działa coś takiego:

    L={};
    

    (zaczynamy z pustą listą) i dodajemy element po elemencie w pętli:

    For[i=0, i<10, i++, L=Append[L, i]]
    

    a lista w koncu ma wartosci:

    {0,1,2,3,4,5,6,7,8,9}
    

Matlab

  1. Jak utworzyć macierz o wymiarach $n\times m$, której zawartością są same zera?

    Służy do tego funkcja zeros:

    A = zeros(n, m)
    
  2. W jaki sposób wstrzymać wypisywanie zawartości wyników obliczeń (na przykład tablic) na ekranie?

    Na końcu polecenia należy umieścić średnik.

  3. W jaki sposób dodać element do tablicy?

    Matlab jest dosyć odporny na działania na tablicach. W szczególności można napisać tak:

    >> z=[1,2,3]
    z =
         1     2     3
    >> z(4,4)=7
    z =
         1     2     3     0
         0     0     0     0
         0     0     0     0
         0     0     0     7
    

    najpierw nadaliśmy wartości tablicy o jednym wierszu i trzech kolumnach, a następnie dodaliśmy element w czwartym wierszu i kolumnie — tablica została automatycznie rozbudowana.

    Można też tak:

    >> for n=1:3
    d(n)=n
    end
    d =
         1
    d =
         1     2
    d =
         1     2     3
    

    albo tak:

    e=[]     
    >> for n=1:3
    e(end+1)=n
    end       
    e =
         1
    e =
         1     2
    e =
         1     2     3
    
  4. Jak wczytać dane i pozbyć się linii zawierających NaN?

    1. Ściągamy dane, na przykład plik temperatura_29012017_0001.csv.xz:

      wget https://temisto.immt.pwr.wroc.pl/~myszka/Dane_Numeryczne/temperatura_29012017_0001.csv.xz
      
    2. Rozpakowujemy

      xz -d temperatura_29012017_0001.csv.xz
      

      i dostajemy plik temperatura_29012017_0001.csv.

    3. W pliku tym pierwszy wiersz to --- AVERAGE 300, kolejnych 288 wartości to pomiary (temperatury) z krokiem 300 sekund. Następnie (w lini 290) jest wiersz --- AVERAGE 1800, w linii 627 --- AVERAGE 86400, a w linii 993 — --- AVERAGE 2678400.

    4. Od linii 1114 sytuacja zaczyna się powtarzać, ale teraz będą wartości minimalne (agregacja danych polega nie na uśrednianiu, ale na wyliczaniu minimum z pomiarów). Czyli --- MIN 300, 1800, 86400, 2678400.

    5. Od linii 2227 są wartości maksymalne.

    6. Przetwarzanie najlepiej robić na pomiarach z doby (uśrednianie co 5 minut) lub tygodnia (uśrednianie co 30 minut).

    7. Plik można automatycznie ,,pociąć" na mniejsze kawałki używając dostępnego programu napisanego w awk.

      Pobieramy program:

      wget https://myszka.kmim.wm.pwr.edu.pl/uploads/numeryczne/awk/cut.awk>
      

      Uruchamiamy:

      gawk -f cut.awk temperatura_29012017_0001.csv
      

      W wyniku jego działania dostajemy pliki o nazwach:

      AVERAGE300.dat 
      AVERAGE1800.dat
      AVERAGE86400.dat 
      AVERAGE2678400.dat 
      MIN300.dat 
      MIN1800.dat
      MIN86400.dat 
      MIN2678400.dat 
      MAX300.dat MAX1800.dat 
      MAX86400.dat
      MAX2678400.dat
      
    8. Dane zawierać mogą wartości NaN. W tym przypadku oznacza to, że w danej chwili nie udało się dokonać pomiarów. Ogólne znaczenie tego symbolu opisuje, na przykład, Wikipedia: https://pl.wikipedia.org/wiki/NaN Po zaimportowaniu danych trzeba się tych wierszy pozbyć. W opisywanym przypadku (plik temperatura_29012017_0001.csv) wartości NaN występują w pliku AVERAGE86400

      grep NaN AVERAGE86400 | wc -l`
      

      Jest ich 15 sztuk.

    9. Uruchamiamy Matlab i wczytujemy dane. Poprosiłem Matlaba o wygenerowanie skrypu dokonującego importu:

      %% Import data from text file.
      % Script for importing data from the following text file:
      %
      %    /home/myszka/przyklad/AVERAGE86400.dat
      %
      filename = '/home/myszka/przyklad/AVERAGE86400.dat';
      delimiter = ' ';
      fileID = fopen(filename,'r');
      formatSpec = '%f%f%[^\n\r]';
      dataArray = textscan(fileID, formatSpec, 'Delimiter', delimiter,   'MultipleDelimsAsOne', true, 'EmptyValue' ,NaN, 'ReturnOnError', false);
      fclose(fileID);
      czas = dataArray{:, 1};
      temperatura = dataArray{:, 2};
      clearvars filename delimiter formatSpec fileID dataArray ans;
      
    10. Dalsze przetwarzanie jest dosyć proste. Trzeba znaleźć wszystkie te miejsca, w których pojawiają się NaNy (Dokumentacja Matlaba) (albo raczej te, w których NaNów nie ma):

      nans = ~isnan(temperatura);
      

      nans to tablica zawierająca zera tam gdzie są NaNy i 1 w pozostałych miejscach). Selekcjonujemy dane:

      Temperatura = temperatura(nans) 
      Czas = czas(nans)
      

      Przy okazji sprawdźmy minimalną i maksymalną wartość zmierzonej temperatury: max(Temperatura) poda, że ta wartość to 3.8584e+04 a min(Temperatura) to -100.8635 Jak widać dane zawierają błędy pomiarowe. find(Temperatura==min(Temperatura)) zwraca wartość 347 (to numer wiersza), aTemperatura(find(Temperatura==min(Temperatura))=[]; pozwala usunąć tę wartość. Ale lepiej robić to etapami (bo trzeba również usunąć odpowiadający jej znacznik czasowy)

      i=find(Temperatura==min(Temperatura); 
      Temperatura(i)=[];
      Czas(i)=[];
      

      Podobnie z wartością maksymalną:

      i=find(Temperatura==max(Temperatura)); 
      Temperatura(i)=[];
      Czas(i)=[];
      

      Niestety, dane dalej zawierają błędy: max(T) wynosi 2.1329e+04 (ale min(T) to już sensowne -7.6313).

    11. Na koniec można zrobić wykres danych z miesiąca:

      plot(Czas, Temperatura);
      

      Niestety, wykres nie jest piękny (zwłaszcza jeżeli chodzi o opis osi X. Problemem jest format zapisu czasu. Matlab używa formatu POSIX

      Zależność między formatami jest następująca:

      posixtime = unix_time/86400 + datenum(1970,1,1);
      

      Teraz wykres

      plot(Czas / 86400  + datenum(1970, 1, 1), Temperatura);
      

      i po zdefiniowaniu formatu osi X

      datetick('x','dd-mm-yy')
      

      wygląda znacznie lepiej

  5. Jak zrobić wykres, którego kolory zależą od jakiejś wartości?

    Niech

    x = 0:0.01:10;
    y = sin(x);
    

    to dane do naszego wykresu.

    Chcemy sprawić akby wartości większe od zadanej wartość $\alpha$ były w innym kolorze niż mniejsze. (Kwestię wzrostu/spadku można rozwiązać analogicznie).

    alfa=0.2
    

    Wynikiem operacji

    y > alfa
    

    jest wektor współrzędnych, dla których ten warunek jest spełniony; zatem

    wieksze = (y > alfa)
    

    Teraz musimy zrobić dwie kopie kolumny y; zmodyfiujemy je tak, żeby jedna zawierała jedynie wartości większe, druga mniejsze. Te, których nie będzie zamienimy na wartość NaN:

    gora = y;
    dol = y;
    gora(wieksze) = NaN;
    dol(~wieksze) = NaN;
    

    Sam wykres to już zabawa:

    plot(x, dol, 'r', x, gora, 'g')
    

Jupyter/Python

  1. W jaki sposób zapisać otrzymany w Jupyterze wykres (czy ogólniej obrazek) wyświetlany inline?

    1. Najprościej tak jak w przeglądarce zapisuje się obrazki: klikamy prawym klawiszem myszy na obrazku i z menu wybieramy ,,Zapisz grafikę jako\ldots’’. Obrazek będzie w formacie PNG.
    2. Inna metoda to użycie funkcji savefig() tam gdzie (w przykładowych notatnikach) używana jest funkcja show(). Jako argument funkcji savefig() podajemy nazwę pliku. Na podstawie rozszerzenia system podejmie decyzję w jakim formacie wykres zapisać. Może to być: png, svg, pdf, ps, eps.
  2. W jaki sposób zapisać tablicę danych numpy do pliku CSV?

    Jeżeli nasza tablica z danymi nazywa się $a$ to następujące polecanie zapiszą jako plik CSV.

    import numpy
    numpy.savetxt("foo.csv",  a,  delimiter = ",")    
    

Ogólne

  1. Czy do programowania należy wykorzystywać wyłącznie Matlab i/lub Mathematicę?

    Nie. Można użyć dowolnego języka programowania dostępne w laboratorium (C, C++, Python, Jupyter, Mathematica, Matlab, Scilab, Blockly,…). W miarę potrzeby i dostępności) mogą zostać doinstalowane kolejne. Proszę zgłaszać potrzeby.

Poprzedni
Następny