<SYSTEM_TASK:>
Given the following text description, write Python code to implement the functionality described below step by step
<END_TASK>
<USER_TASK:>
Description:
 Numpy
numpy je paket (modul) za (efikasno) numeričko računanje u Pythonu. Naglasak je na efikasnom računanju s nizovima, vektorima i matricama, uključivo višedimenzionalne stukture. Napisan je u C-u i Fortanu te koristi BLAS biblioteku.
Step1:  Kreiranje nizova pomoću numpy modula
Step2:  Možemo koristiti i funkcije numpy.shape, numpy.size
Step3:  Koja je razlika između numpy.ndarray tipa i standardnih lista u Pythonu?
liste u Pythonu mogu sadržavati bilo kakve vrste objekata, to nije slučaj s numpy.ndarray
numpy.ndarray nisu dinamički objekti
Step4:  Kako je M statički objekt, ne možemo napraviti ovo
Step5:  Naravno, ovo je ok
Step6:  dtype se može eksplicitno zadati
Step7:  Tipično dtype su
Step8:  Učitavanje podataka
Često učitavamo podatke iz datoteka (lokalno ili s weba). Važni formati su cvs (comma-separated values) i tsv (tab-separated values).
Step9:  Uz numpy.savetxt možemo napraviti i obrnuto.
Step10:  Postoji i interni format za numpy nizove
Step11:  Rad s nizovima
Indeksiranje funkcionira standardno.
Step12:  Naravno, možemo koristiti i 
Step13:  S negativnim indeksima računamo od kraja niza
Step14:  Naravno, iste operacije imamo i za višedimenzionalne nizove.
Step15:  Možemo koristiti i tzv. maske
Step16:  Zanimljiviji primjer
Step17:  Funkcije na nizovima
Step18:  U sljedećem primjeru take djeluje na listu, a izlaz je array
Step19:  Funkcija choose
Step20:  Što radi ova funkcija?
Vektorizacija koda
Što je više operacija s nizovima, to će kod generalno biti brži.
Step21:  Defaultne operacije na nizovima su uvijek definirane po elementima.
Step22:  Kako doći do standardnog umnoška?
Step23:  Matrice mogu biti i višedimenzionalne
Step24:  Postoji i tip matrix. Kod njega operacije +, -, * se ponašaju onako kako smo navikli.
Step25:  Naravno, dimenzije trebaju biti kompatibilne.
Step26:  Još neke funkcije
Step27:  Adjungiranje
Step28:  Za izvlačenje realnog, odnosno imaginarnog dijela
Step29:  Izvlačenje osnovih informacija iz nizova
Step30:  Prosječna dnevna temperatura u Stockholmu u zadnjiih 200 godina je bila 6.2 C.
Step31:  Naravno, sve ove operacije možemo raditi na dijelovima nizova.
Step32:  Format je
Step33:  Sada nije problem doći do histograma za prosječne mjesečne temperature u par redaka.
Step34:  Rad s višedimenzionalnim podacima
Step35:  Oblik niza se može promijeniti bez da se dira memorija, dakle mogu se primijenjivati i na veliku količinu podataka.
Step36:  Funkcija flatten radi kopiju.
Step37:  Kopiranje nizova
Step38:  Ako želimo napraviti novu kopiju, koristimo funkciju copy
Step39:  Funkcija enumerate nam daje i element i njegov indeks
Step41:  Vektorizacija funkcija
Step43:  To smo mogli napraviti i ručno.
Step44:  Eksplicitno pretvaranje podataka. Uvijek stvara novi niz.
<ASSISTANT_TASK:>
Python Code:
from numpy import *
Explanation: Numpy
numpy je paket (modul) za (efikasno) numeričko računanje u Pythonu. Naglasak je na efikasnom računanju s nizovima, vektorima i matricama, uključivo višedimenzionalne stukture. Napisan je u C-u i Fortanu te koristi BLAS biblioteku.
End of explanation
v = array([1,2,3,4])
v
M = array([[1, 2], [3, 4]])
M
type(v), type(M)
v.shape
M.shape
v.size, M.size
Explanation: Kreiranje nizova pomoću numpy modula
End of explanation
shape(M)
size(M)
Explanation: Možemo koristiti i funkcije numpy.shape, numpy.size
End of explanation
M.dtype
Explanation: Koja je razlika između numpy.ndarray tipa i standardnih lista u Pythonu?
liste u Pythonu mogu sadržavati bilo kakve vrste objekata, to nije slučaj s numpy.ndarray
numpy.ndarray nisu dinamički objekti: pri kreiranju im je određen tip
za numpy.ndarray implementirane su razne efikasne metode važne u numerici
de facto sva računanja se odvijaju u C-u i Fortranu pomoću BLAS rutina
dtype (data type) nam daje informaciju o tipu podataka u nizu:
End of explanation
M[0,0] = "hello"
Explanation: Kako je M statički objekt, ne možemo napraviti ovo:
End of explanation
M[0,0]=5
Explanation: Naravno, ovo je ok:
End of explanation
M = array([[1, 2], [3, 4]], dtype=complex)
M
Explanation: dtype se može eksplicitno zadati:
End of explanation
x = arange(0, 10, 1) # argumenti: početak, kraj, korak
x # 10 nije u nizu!
x = arange(-1, 1, 0.1)
x
# ovdje su i početak i kraj uključeni!
linspace(0, 10, 25)
logspace(0, 10, 10, base=e)
x, y = mgrid[0:5, 0:5] # slično kao meshgrid u MATLAB-u
x
y
from numpy import random
# uniformna distribucija na [0,1]
random.rand(5,5)
# standardna normalna distribucija
random.randn(5,5)
# dijagonalna matrica
diag([1,2,3])
# matrica sa sporednom dijagonalom
diag([1,2,3], k=1)
zeros((3,3))
ones((3,3))
Explanation: Tipično dtype su: int, float, complex, bool, object, itd.
Ali možemo biti i eksplicitni vezano za veličinu registra: int64, int16, float128, complex128.
Funkcije koje generiraju nizove
End of explanation
!head tpt-europe.csv
data = genfromtxt('tpt-europe.csv')
data.shape, data.dtype
Explanation: Učitavanje podataka
Često učitavamo podatke iz datoteka (lokalno ili s weba). Važni formati su cvs (comma-separated values) i tsv (tab-separated values).
End of explanation
M = random.rand(3,3)
M
savetxt("random-matrix.csv", M)
!cat random-matrix.csv
savetxt("random-matrix.csv", M, fmt='%.5f') # s fmt specificiramo format
!cat random-matrix.csv
Explanation: Uz numpy.savetxt možemo napraviti i obrnuto.
End of explanation
save("random-matrix.npy", M)
!file random-matrix.npy
load("random-matrix.npy")
M.itemsize # byte-ovi po elementu
M.nbytes
M.ndim
Explanation: Postoji i interni format za numpy nizove:
End of explanation
v[0]
 M[1,1]
M
M[1]
Explanation: Rad s nizovima
Indeksiranje funkcionira standardno.
End of explanation
M[1,:] # redak 1
M[:,1] # stupac 1
M[1,:] = 0
M[:,2] = -1
M
A = array([1,2,3,4,5])
A
A[1:3]
A[1:3] = [-2,-3]
A
A[::]
A[::2]
A[:3]
A[3:]
Explanation: Naravno, možemo koristiti i : operator:
End of explanation
A = array([1,2,3,4,5])
A[-1] # zadnji element niza
A[-3:] # zadnja tri elementa
Explanation: S negativnim indeksima računamo od kraja niza:
End of explanation
A = array([[n+m*10 for n in range(5)] for m in range(5)])
A
A[1:4, 1:4]
A[::2, ::2]
indeksi_redaka = [1, 2, 3]
A[indeksi_redaka]
indeksi_stupaca = [1, 2, -1]
A[indeksi_redaka, indeksi_stupaca]
Explanation: Naravno, iste operacije imamo i za višedimenzionalne nizove.
End of explanation
B = array([n for n in range(5)])
B
maska = array([True, False, True, False, False])
B[maska]
maska = array([1,0,1,0,0], dtype=bool)
B[maska]
Explanation: Možemo koristiti i tzv. maske: ako je maska numpy niz tipa bool, tada se izabiru oni elementi koji u maski odgovaraju vrijednosti True.
End of explanation
x = arange(0, 10, 0.5)
x
maska = (5 < x) * (x < 7.5)
maska
x[maska]
Explanation: Zanimljiviji primjer:
End of explanation
indeksi = where(maska)
indeksi
x[indeksi]
print(A)
diag(A)
diag(A, -1)
v2 = arange(-3,3)
v2
indeksi_redaka = [1, 3, 5]
v2[indeksi_redaka]
v2.take(indeksi_redaka)
Explanation: Funkcije na nizovima
End of explanation
take([-3, -2, -1,  0,  1,  2], indeksi_redaka)
Explanation: U sljedećem primjeru take djeluje na listu, a izlaz je array:
End of explanation
koji = [1, 0, 1, 0]
izbori = [[-1,-2,-3,-4], [5,4,3,2]]
choose(koji, izbori)
Explanation: Funkcija choose:
End of explanation
v1 = arange(0, 5)
v1 * 2
v1 + 2
print(A)
A * 2, A + 2
Explanation: Što radi ova funkcija?
Vektorizacija koda
Što je više operacija s nizovima, to će kod generalno biti brži.
End of explanation
A * A
v1 * v1
A.shape, v1.shape
print(A,v1)
A * v1
Explanation: Defaultne operacije na nizovima su uvijek definirane po elementima.
End of explanation
dot(A, A)
A @ A # nova operacija definirana u Python-u 3.5+
matmul(A,A) # @ je zapravo pokrata za matmul, dot i matmul nisu iste operacije (poklapaju se na 1D i 2D nizovima)
dot(A, v1)
A @ v1
v1 @ v1 # analogno dot(v1, v1)
Explanation: Kako doći do standardnog umnoška?
End of explanation
a = random.rand(8,13,13)
b = random.rand(8,13,13)
matmul(a, b).shape
Explanation: Matrice mogu biti i višedimenzionalne
End of explanation
M = matrix(A)
v = matrix(v1).T # da bi dobili stupčasti vektor
v
M*M
M*v
# skalarni produkt
v.T * v
v + M*v
Explanation: Postoji i tip matrix. Kod njega operacije +, -, * se ponašaju onako kako smo navikli.
End of explanation
v = matrix([1,2,3,4,5,6]).T
shape(M), shape(v)
M * v
Explanation: Naravno, dimenzije trebaju biti kompatibilne.
End of explanation
C = matrix([[1j, 2j], [3j, 4j]])
C
conjugate(C)
Explanation: Još neke funkcije: inner, outer, cross, kron, tensordot.
End of explanation
C.H
Explanation: Adjungiranje:
End of explanation
real(C) # isto što i C.real
imag(C) # isto što i C.imag
angle(C+1) # u MATLAB-u je to funkcija arg, dakle argument (faza) kompleksnog broja
abs(C)
from numpy.linalg import inv, det
inv(C) # isto što i C.I 
C.I * C
det(C)
det(C.I)
Explanation: Za izvlačenje realnog, odnosno imaginarnog dijela: real i imag:
End of explanation
# u stockholm_td_adj.dat su podaci o vremenu za Stockholm
dataStockholm = genfromtxt('stockholm_td_adj.dat')
dataStockholm.shape
# temperatura se nalazi u 4. stupcu (znači stupcu broj 3)
mean(dataStockholm[:,3])
Explanation: Izvlačenje osnovih informacija iz nizova
End of explanation
std(dataStockholm[:,3]), var(dataStockholm[:,3])
dataStockholm[:,3].min()
dataStockholm[:,3].max()
d = arange(0, 10)
d
sum(d)
prod(d+1)
# kumulativa suma
cumsum(d)
# kumulativan produkt
cumprod(d+1)
# isto što i: diag(A).sum()
trace(A)
Explanation: Prosječna dnevna temperatura u Stockholmu u zadnjiih 200 godina je bila 6.2 C.
End of explanation
!head -n 3 stockholm_td_adj.dat
Explanation: Naravno, sve ove operacije možemo raditi na dijelovima nizova.
End of explanation
# mjeseci su 1.,..., 12.
unique(dataStockholm[:,1])
maska_velj = dataStockholm[:,1] == 2
mean(dataStockholm[maska_velj,3])
Explanation: Format je: godina, mjesec, dan, prosječna dnevna temperatura, najniža, najviša, lokacija.
Recimo da nas zanimaju samo temperature u veljači.
End of explanation
mjeseci = arange(1,13)
mjeseci_prosjek = [mean(dataStockholm[dataStockholm[:,1] == mjesec, 3]) for mjesec in mjeseci]
from pylab import *
%matplotlib inline
fig, ax = subplots()
ax.bar(mjeseci, mjeseci_prosjek)
ax.set_xlabel("Mjesec")
ax.set_ylabel("Prosj. mj. temp.");
Explanation: Sada nije problem doći do histograma za prosječne mjesečne temperature u par redaka.
End of explanation
m = rand(3,3)
m
m.max()
# max u svakom stupcu
m.max(axis=0)
# max u svakom retku
m.max(axis=1)
Explanation: Rad s višedimenzionalnim podacima
End of explanation
A
n, m = A.shape
B = A.reshape((1,n*m))
B
B[0,0:5] = 5 # promijenili smo B
B
A # a time smo promijenili i A
Explanation: Oblik niza se može promijeniti bez da se dira memorija, dakle mogu se primijenjivati i na veliku količinu podataka.
End of explanation
B = A.flatten()
B
B[0:5] = 10
B
A # A je sad ostao isti
v = array([1,2,3])
shape(v)
# pretvorimo v u matricu
v[:, newaxis]
v[:,newaxis].shape
v[newaxis,:].shape
a = array([[1, 2], [3, 4]])
# ponovimo svaki element tri puta
repeat(a, 3)
tile(a, 3)
b = array([[5, 6]])
concatenate((a, b), axis=0)
concatenate((a, b.T), axis=1)
vstack((a,b))
hstack((a,b.T))
Explanation: Funkcija flatten radi kopiju.
End of explanation
A = array([[1, 2], [3, 4]])
A
# B je isto što i A (bez kopiranja podataka)
B = A
Explanation: Kopiranje nizova
End of explanation
B = copy(A)
v = array([1,2,3,4])
for element in v:
    print (element)
M = array([[1,2], [3,4]])
for row in M:
    print ("redak {}".format(row))
    
    for element in row:
        print (element)
Explanation: Ako želimo napraviti novu kopiju, koristimo funkciju copy:
End of explanation
for row_idx, row in enumerate(M):
    print ("indeks retka {} redak {}".format(row_idx, row))
    
    for col_idx, element in enumerate(row):
        print ("col_idx {} element {}".format(col_idx, element))
        M[row_idx, col_idx] = element ** 2
Explanation: Funkcija enumerate nam daje i element i njegov indeks:
End of explanation
def Theta(x):
    
    Sklarna verzija step funkcije.
    
    if x >= 0:
        return 1
    else:
        return 0
Theta(array([-3,-2,-1,0,1,2,3]))
Theta_vec = vectorize(Theta)
Theta_vec(array([-3,-2,-1,0,1,2,3]))
Explanation: Vektorizacija funkcija
End of explanation
def Theta(x):
    
    Vektorska verzija step funkcije.
    
    return 1 * (x >= 0)
Theta(array([-3,-2,-1,0,1,2,3]))
# radi naravno i za skalare
Theta(-1.2), Theta(2.6)
M
if (M > 5).any():
    print ("barem jedan element iz M je veći od 5")
else:
    print ("svi elementi iz M su manji ili jednaki od 5")
if (M > 5).all():
    print ("svi elementi iz M su veći od 5")
else:
    print ("barem jedan element je manji ili jednak od 5")
Explanation: To smo mogli napraviti i ručno.
End of explanation
M.dtype
M2 = M.astype(float)
M2
M2.dtype
M3 = M.astype(bool)
M3
from verzije import *
from IPython.display import HTML
HTML(print_sysinfo()+info_packages('numpy,matplotlib'))
Explanation: Eksplicitno pretvaranje podataka. Uvijek stvara novi niz.
End of explanation
<END_TASK>