NumPy ne permite sa facem operatii matematice asupra fiecarui element al unui sir in parte fara a fi nevoie de bucle repetitive.

Putem efectua operatii matematice precum adunarea, scaderea, inmultirea si impartirea direct pe siruri cu NumPy. Exemplu:

import numpy as np
a=np.array([1, 2, 3])
b=np.array([4, 5, 6])
add=a+b
print(add)
dif=a-b
print(dif)
inmul=a*b
print(inmul)
div=a/b
print(div)

In consola o sa vedem:
[5 7 9]
[-3 -3 -3]
[ 4 10 18]
[0.25 0.4  0.5 ]

Exista si un alt timp de operatiuni care se aplica fiecarui element individual din sir fara a fi nevoia de mai multe siruri. Exemplu:

import numpy as np
a=np.array([-7, -2, 5, 2, -3, -1])
result=np.absolute(a)
print(result)

In consola o sa vedem:

[7 2 5 2 3 1]

Operatiile binare in NumPy se aplica element cu element si se formeaza un sir nou. Putem sa folosim toti operatorii aritmetici de baza. In cazul operatorilor +=, -= si =, sirul existent este schimbat. Exemplu:

import numpy as np 
a=np.array([1, 4, 6])
b=np.array([2, 5, 7])
result=np.add(a, b)
print(result)

In consola o sa vedem:

[ 3  9 13]

NumPy ofera functii matematice familiare precum sin, cos, exp etc. Aceste functii opereaza element cu element pe un sir, producand un alt sir ca rezultat. Exemplu:

import numpy as np
a=np.array([0, np.pi/2, np.pi])
print(np.sin(a))
a=np.array([1, 2, 3, 4, 5])
print(np.exp(a))
print(np.sqrt(a))

[0.0000000e+00 1.0000000e+00 1.2246468e-16]
[  2.71828183   7.3890561   20.08553692  54.59815003 148.4131591 ]
[1.         1.41421356 1.73205081 2.         2.23606798]

Putem sa folosim np.sort() pentru a sorta un sir folosind NumPy. Exemplu:

import numpy as np
dtype = [
    ('nume',     'S10'),  
    ('an_absol',  int),   
    ('medie_fin', float)   
]
values = [
    ('Radu',   2023, 9.92),
    ('Mihai',  2015, 7.98),
    ('George', 2006, 8.22),
    ('Andrei', 2025, 5.87),
    ('Alex',   2011, 7.63),
]
arr = np.array(values, dtype=dtype)
print(np.sort(arr, order='nume'))
print(np.sort(arr, order='medie_fin'))
print(np.sort(arr, order='an_absol'))

In consola o sa vedem:

[(b'Alex', 2011, 7.63) (b'Andrei', 2025, 5.87) (b'George', 2006, 8.22)
 (b'Mihai', 2015, 7.98) (b'Radu', 2023, 9.92)]
[(b'Andrei', 2025, 5.87) (b'Alex', 2011, 7.63) (b'Mihai', 2015, 7.98)
 (b'George', 2006, 8.22) (b'Radu', 2023, 9.92)]
[(b'George', 2006, 8.22) (b'Alex', 2011, 7.63) (b'Mihai', 2015, 7.98)
 (b'Radu', 2023, 9.92) (b'Andrei', 2025, 5.87)]

In continuare o sa gasiti niste operatii mai avansate.

1.Stacking: Multe siruri pot sa fie suprapuse pe diferite axe.

np.vstack: Pentru a le suprapune pe axa verticala.

np.hstack: Pentru a le suprapune pe axa orizontala.

np.column_stack: Pentru a suprapune siruri unidimensionale ca si coloane pentru sirurile bidimensionale.

np.concatenate: Pentru a suprapune siruri pe axe specificate.

Haideti sa vedem un exemplu:

import numpy as np
a=np.array([[1, 2], [3, 4]])
b=np.array([[5, 6], [7, 8]])
print("Suprapunere verticala")
print(np.vstack((a,b)))
print("Suprapunere orizontala")
print(np.hstack((a,b)))
c=np.array([5,6])
print("Suprapunere pe coloana")
print(np.column_stack((a,c)))
print("Concatenare pe a doua axa")
print(np.concatenate((a,b),1))

In consola o sa vedem:

Suprapunere verticala
[[1 2]
 [3 4]
 [5 6]
 [7 8]]
Suprapunere orizontala
[[1 2 5 6]
 [3 4 7 8]]
Suprapunere pe coloana
[[1 2 5]
 [3 4 6]]
Concatenare pe a doua axa
[[1 2 5 6]
 [3 4 7 8]]

2.Splitting: Pentru a taia un sir avem urmatoarele functii:

np.hsplit: Pentru a taia pe orizontala.

np.vsplit: Pentru a taia pe verticala.

np.array_split: Pentru a taia pe axe specifice.

import numpy as np
a = np.array([[1, 3, 5, 7, 9, 11], [2, 4, 6, 8, 10, 12]])
print("Taiem pe orizontala")
print(np.hsplit(a,2))
print("Taiem pe verticala")
print(np.vsplit(a,2))

In consola o sa vedem:

Taiem pe orizontala
[array([[1, 3, 5],
       [2, 4, 6]]), array([[ 7,  9, 11],
       [ 8, 10, 12]])]
Taiem pe verticala
[array([[ 1,  3,  5,  7,  9, 11]]), array([[ 2,  4,  6,  8, 10, 12]])]

3.Broadcasting: Este o metoda folosita pentru gestionarea sirurilor cu dimensiuni diferite in timpul operatiilor matematice. Aceasta metoda permite sirurilor mai mici sa fie extinse automat peste siruri mai mari pentru a le face compatibile ca forma. Asta duce la implementari eficiente ale algoritmului fara a mai crea copii inutile de date. Regula de Broadcasting zice ca fie ambele siruri implicate intr-o operatie sunt egale fie una dintre ele este 1. Haideti sa vedem un exemplu:

A: (4 x 3)

B:     (4)

Acum folosind metoda de broadcasting pe B il transformam in: (1 x 4)

Acum haideti sa le comparam:

A: (4 x 3)

B: (1 x 4)

Pe axa 0 avem 1vs4 acestea sunt compatibile.

Pe axa 1 avem 3vs4 acestea nu sunt compatibile pentru ca incalca regula de broadcasting.

Haideti sa ne mai luam un exemplu:

A: (4 x 3)

B:     (3)

Facem broadcasting pe B si il transformam in (1 x 3). Haideti sa le comparam:

A: (4 x 3)

B: (1 x 3)

Pe axa 0 avem 4vs1 sunt compatibile

Pe axa 1 avem 3vs3 si acestea sunt compatibile

Inseamna ca rezultatul nostru este: (4 x 3)

Haideti sa ne luam si un exemplu putin mai complicat:

A: (7 x 1 x 6 x 1)

B: (3 x 1 x 5)

Haideti sa facm broadcasting pe B si il transformam in: (1 x 3 x 1 x 5). Haideti sa le comparam:

A: (7 x 1 x 6 x 1)

B: (1 x 3 x 1 x 5)

Pe axa 0 avem 7vs1 sunt compatibile

Pe axa 1 avem 1vs3 sunt compatibile

Pe axa 2 avem 6vs1 sunt compatibile

Pe axa 3 avem 1vs5 sunt compatibile

Deci rezultaul este: (7 x 3 x 6 x 5)

Haideti sa vedem o problema simpla:

import numpy as np
a=np.array([1.0,  2.0, 3.0])
b=2.0
print(a*b)
c=np.array([2.0, 2.0, 2.0])
print(a*c)

In consola o sa vedem:

[2. 4. 6.]
[2. 4. 6.]

In codul de mai sus NumPy i-a facut automat broadcasting lui b in [2.0, 2.0, 2.0] pentru al putea inmulti cu a.

Haideti sa mai luam un exemplu care sa se afle in mai multe dimensiuni:

import numpy as np
a = np.array([0.0, 10.0, 20.0, 30.0])
b = np.array([0.0, 1.0, 2.0])
print(a[:, np.newaxis] + b)

In consola o sa vedem:

[[ 0.  1.  2.]
 [10. 11. 12.]
 [20. 21. 22.]
 [30. 31. 32.]]

Urmatoarea imagine explica cum s-a facut broadcasting:

1

4.Lucrand cu date si timp: NumPy are un tip nativ de date pentru siruri care ofera functionalitatea datetime. Tipul de date se numeste "datetime64", deoarece "datetime" este utilizat de biblioteca datetime din Python. Mai multe exemple le gasitit in codul de mai jos:

import numpy as np

azi= np.datetime64('2017-02-12')
print("Data de azi este:", azi)
print("Anul este:", np.datetime64(azi, 'Y'))

dates = np.arange('2017-02', '2017-03', dtype='datetime64[D]')
print("\nDatele din februarie, 2017:\n", dates)
print("Azi este februarie:", azi in dates)

dur = np.datetime64('2017-05-22') - np.datetime64('2016-05-22')
print("\nNumar de zile:", dur)
print("Numar de saptamani:", np.timedelta64(dur, 'W'))

a = np.array(['2017-02-12', '2016-10-13', '2019-05-22'], dtype='datetime64')
print("\nDati sortate in ordine:", np.sort(a))

In consola o sa vedem:
Data de azi este: 2017-02-12
Anul este: 2017
Datele din februarie, 2017:
 ['2017-02-01' '2017-02-02' '2017-02-03' '2017-02-04' '2017-02-05'
 '2017-02-06' '2017-02-07' '2017-02-08' '2017-02-09' '2017-02-10'
 '2017-02-11' '2017-02-12' '2017-02-13' '2017-02-14' '2017-02-15'
 '2017-02-16' '2017-02-17' '2017-02-18' '2017-02-19' '2017-02-20'
 '2017-02-21' '2017-02-22' '2017-02-23' '2017-02-24' '2017-02-25'
 '2017-02-26' '2017-02-27' '2017-02-28']
Azi este februarie: True
Numar de zile: 365 days
Numar de saptamani: 52 weeks
Dati sortate in ordine: ['2016-10-13' '2017-02-12' '2019-05-22']

5.Algebra liniara in NumPy

Modulul de algebra liniara din NumPy ofera metode variate pentru a aplica algebra liniara pe orice sir NumPy. 

Putem gasi:

  • rangul, determinantul, trasarea etc. ale unui sir
  • valorile proprii ale matricelor
  • produsul matricelor, vectorilor si exponentiere matriciala
  • rezolvarea ecuatiilor liniare sau tensoriale si multe altele

Exemplu:

import numpy as np

A = np.array([[6, 1, 1],
              [4, -2, 5],
              [2, 8, 7]])

print("Rangul lui A:", np.linalg.matrix_rank(A))

print("Urma lui A:", np.trace(A))

print("Determinantul lui A:", np.linalg.det(A))

print("Inversul lui A:", np.linalg.inv(A))

print("Matricea la puterea 3:", np.linalg.matrix_power(A, 3))

In consola o sa vedem:

Rangul lui A: 3
Urma lui A: 11
Determinantul lui A: -306.0
Inversul lui A: [[ 0.17647059 -0.00326797 -0.02287582]
 [ 0.05882353 -0.13071895  0.08496732]
 [-0.11764706  0.1503268   0.05228758]]
Matricea la puterea 3: [[336 162 228]
 [406 162 469]
 [698 702 905]]

Sa presupunem ca vrem sa rezolvam urmatorul set de algebra liniara:

x + 2*y = 8
3*x + 4*y = 18

Haideti sa vedem codul:

import numpy as np
# coeficientii
a = np.array([[1, 2], [3, 4]])
# constanele
b = np.array([8, 18])

print("Solutia ecuatilor liniare:", np.linalg.solve(a, b))

In consola o sa vedem: 

Solutia ecuatilor liniare: [2. 3.]

Ultima modificare: sâmbătă, 16 august 2025, 12:39