# numpy - numerical python - biblioteka do obliczeń naukowych
# numpy jest szybszy niż standardoe operacje na listach w Pythonie

# Lista - zbiór danych, edytowalna, może przechowywać różne typy
# Tablica (array) - struktura danych, przechowuje te same typy

# Przez to że tablica wymaga tego samego typy, efektywniej zarządza pamięcią - jest szybsza

# Lista jest przeznaczona do budowania dynamicznych struktur (nie wiecie do końca co wpadnie)
# Tablica jest do dużych zbiorów danych (np. analiza danych albo uczenie maszynowe)

# Tablice Numpy oferują bezpośrednie operacje matemtyczne na strukturach (listy nie)

import numpy as np

def print_array():
    arr = np.array([[0,2,3], [4,5,6], [7,8,9]])
    print(f"Tablica {arr}")
    print(f"Pierwszy elem {arr[0]}")
    print(f"Pierwszy zagnieżdżony elem {arr[0][0]}")
    print(f"Typ obiektu tablicy {type(arr)}")
    return arr

arr = print_array()

def shapeshifter(arr):
    print("Kształt tablicy 9x1")
    print(arr.reshape(9,1))
    print("Kształt tablicy 1x9")
    print(arr.reshape(1,9))
    print("Kształt tablicy 3x?")
    print(arr.reshape(3,-1))
    print("Podział tablicy na 3 nowe tablice")
    newarr = np.array_split(arr.reshape(-1,9), 3) 
    print(newarr)

shapeshifter(arr)

def data_format():
    arr = np.array([[1.1, 2.2, 3.4], ["kot", 12, "ola"], ['a', 'x', 'd']], dtype="U")
    print(arr) # rzutowanie na stringa
    print(type(arr))

data_format()

def sorted_ndarray():
    arr = np.array([[5,2,9], [8,1,4], [3,7,6]])
    print(f"Tablica przed sortowaniem {arr}")
    print(f"Tablica po sortowaniu {np.sort(arr)}")

sorted_ndarray()
