# ---
# jupyter:
#   jupytext:
#     text_representation:
#       extension: .py
#       format_name: light
#       format_version: '1.5'
#       jupytext_version: 1.14.4
#   kernelspec:
#     display_name: Python 3
#     language: python
#     name: python3
# ---

# # Основы NumPy
# <hr>

# **Основа NymPy (Numerical Python)** -  это объект **ndarray**, который используется для представления **N-мерного массива**; это быстрый и гибкий контейнер для хранения большим наборов данных в Python. Массивы позволяют выполнять математические перации над целыми блоками данных. По сути это обычный list с большим набором возможностей. 

# У любого **numpy-массива (array)** есть атрибут **shape** - кортеж, описывающий размер по каждому измерению, и атрибут
# **dtype** - объект, описывающий тип данных в массив; **ndim** - количество измерений массива (одномерный, двухмерный и т.д.). **tolist()** - конвертирует array в обычный python list

# **Array vs list:**
# * Array используют меньше памяти, чем списки
# * Array обладают значительно большей функциональностью
# * Array требуют, чтобы данные были однородными; списки нет
#

# ## **1D (одномерные массивы, списки, векторы), 2D (двумерные массивы, матрицы) и 3D (куб)-arrays:**

# Четырехмерный, пятимерный и более массив — это **тензор**.

# ## Работа с NumPy

import numpy as np

# +
data = [1, 2, 3, 4, 5]

arr = np.array(data) # создание из list

print(arr)
print(arr.shape)
print(arr.dtype)
print(arr.ndim)
# -

# **Типы данных NumPy:**
#
# * np.int64          // Signed 64-bit integer types
# * np.float32        // Standard double-precision floating point
# * np.complex        // Complex numbers represented by 128 floats>
# * np.bool           // Boolean type storing TRUE and FALSE values
# * np.object         // Python object type
# * np.string_        // Fixed-length string type>
# * np.unicode_       // Fixed-length unicode type

# +
arr2 = np.array([1, 2, 3, 4, 5])  

print(arr2)
print(arr2.shape)
print(arr2.dtype)
print(arr2.ndim)

# +
arr3 = np.array([1, 2, 3, 4, 5], dtype=np.float) # задаём явно тип данных

print(arr3)
print(arr3.shape)
print(arr3.dtype)
print(arr3.ndim)
print(len(arr3))
print(arr3.size)

# +
arr3 = arr3.astype(np.int64) # приводим все элементы к типу int64

print(arr3)
print(arr3.dtype)

# +
arr4 = np.arange(0, 20, 1.5) 

arr4

# +
arr5 = np.linspace(0, 2, 5) # 5 чисел от 0 до 2

arr5

# +
arr5 = np.linspace(0, 2, 50)

arr5

# +
random_arr = np.random.random((5,))

random_arr
# -

random_arr2 = np.random.random_sample((5,))
random_arr2

# ### Диапазон случайных чисел от [a,b]: (b - a) * np.random() + a, где b > a

# 5 случайных значений от -5 до 10
random_arr3 = (10 - -5) * np.random.random_sample((5,)) - 5
random_arr3

# ## Операции

# +
arr = np.array([1, 2, 3, 4, 5])

arr = np.sqrt(arr)
print(arr)

arr = np.sin(arr)
print(arr)

arr = np.cos(arr)
print(arr)

arr = np.log(arr)
print(arr)

arr = np.exp(arr)
print(arr)

# +
a = np.array([1, 2, 3, 4, 5])
b = np.array([6, 7, 8, 9, 10])

print(a)
print(b)

# +
c = a + b # np.add(a, b)

print(c)
# -

a * b # np.multiply(a,b)

a - b # np.subtract

a / b #np.divide

arr = np.array([1, 2, 3, 4, 5])
arr = arr * 2  # все элементы умножить на 2
print(arr)

arr = arr ** 2  # возводим все элементы в квадрат 
arr

# +
simple_list = [1, 2, 3, 4, 5]
simple_list = simple_list * 2
print(simple_list)

simple_list = simple_list ** 2
# -

# ## Функции агрегаты

arr = np.random.randint(-5, 10, 10)
arr

print(arr.max())
print(arr.min())
print(arr.mean())
print(arr.sum())
print(arr.std())
print(np.median(arr))

arr < 2

# ## Манипуляции с массивами

np.insert(arr, 2, -20) # вставляем 20 в позицию 2 

np.delete(arr, 2) # удаляем элемент во 2 позиции, с матрицами можно укзывать строки или столбцы 

np.sort(arr)

arr2 = np.array([0, 0, 0])
arr = np.concatenate((arr, arr2))
arr

np.array_split(arr, 3) #hsplit, vsplit

# ## Индексы и одномерные массивы 

arr = np.array([1, -2, 3, -4, 5])
arr[0] = 0
print(arr[2])
print(arr[0:2])
print(arr[::-1])
print(arr[arr < 2])
print(arr[(arr < 2) & (arr > 0)])
print(arr[(arr > 4) | (arr < 0)])
arr[1:4] = 0
print(arr)

# ## Матрицы и многомерные массивы

matrix = np.array([(1,2,3),(4,5,6)], dtype=np.float64)
matrix

matrix = np.array([(1,2,3),(4,5,6), (7, 8, 9)])
matrix

matrix = np.array([(1,2,3),(4,5,6),(7, 8, 9)])
matrix

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

matrix = np.array([(1,2,3),(4,5,6), (7, 8, 9)])
matrix
print(matrix.shape)
print(matrix.ndim)
print(matrix.size)

matrix.reshape(1,9)

matrix = np.array([(1,2,3),(4,5,6), (7, 8, 9), (10, 11, 12)])
matrix

matrix.reshape(2,6)

matrix2 = np.random.random((2,2))
matrix2

print(matrix)
matrix = np.resize(matrix, (2,2))
print()
print(matrix)

new_matrix = np.arange(16).reshape(2,8)
new_matrix

# ## Создание специальных матриц

np.zeros((2,3))

np.ones((3,3))

np.eye(5)

np.full((3,3), 9)

np.empty((3,2))

# ## Операции над матрицами

matrix1 = np.array([(1, 2), (3, 4)])
print(matrix1)
print()
matrix2 = np.array([(5, 6), (7, 8)])
print(matrix2)

matrix1 + matrix2 # np.add

matrix1 - matrix2

matrix1 * matrix2

matrix1 / matrix2

matrix1.dot(matrix2) # скалаярное произведение

# **Axis** - ось. 0 -  ось строк, 1 - ось столбцов
#
# https://i.stack.imgur.com/gj5ue.jpg

matrix = np.array([(1,2,3), (4, 5, 6), (7, 8,9)])
matrix

np.delete(matrix,1,axis=0) # удаляет 1 строку матрицы

np.delete(matrix,1,axis=1) # удаляет 1 столбец матрицы

np.sin(matrix)

np.log(matrix)

# При применении определенных функций Numpy, таких как np.mean (),max() и т.д. мы можем указать, по какой оси мы хотим вычислять значения.
#
# Для axis = 0 это означает, что мы применяем функцию к каждому «столбцу» или ко всем значениям, которые встречаются по вертикали.
#
# Для axis = 1 это означает, что мы применяем функцию к каждой «строке» или ко всем значениям по горизонтали.

matrix.sum()

matrix


print(matrix.max())
print(matrix.max(axis=0)) # ищем наибольший элемент по каждой строке

np.mean(matrix, axis=0) # среднее значение идёт по строкам (1 + 4 + 7)/3 = 4

np.mean(matrix, axis=1) # среднее значение идёт по столбцам (1 + 2 + 3)/3 = 2

matrix**2

arr1 = np.array([[1, 2, 3],[4, 5, 6]])
print(arr1)
print()
arr2 = np.array([[7, 8, 9],[10, 11, 12]])
print(arr2)
print()
arr = np.concatenate((arr1,arr2),axis=1) # добавляем arr2 к arr1 как столбцы
arr

arr = np.concatenate((arr1,arr2),axis=0) # добавляем arr2 к arr1 как строки
arr

np.hstack((arr1,arr2))

arr = np.vstack((arr1,arr2))
arr

np.split(arr,2)

np.split(arr,2, axis=0)

np.split(arr,3, axis=1)

np.append(arr, np.array([1, 2, 3]))

# ## Индексация

matrix = np.array([(1, 2, 3), (4, 5, 6), (7, 8, 9)])
matrix

matrix[1,2] # 2 элемент 1 строки

matrix[2] # 2 строка

matrix[:,2] # 2 столбец

matrix[1:3, 0:2] # 0 и 1 столбец, 1  и 2 строки

matrix[matrix > 2]

# # Специальные операции

matrix

matrix.T  # транспонированная 

matrix.flatten() # в массив 

np.linalg.inv(matrix) # обратная матрица 

np.trace(matrix) # след матрицы

np.linalg.det(matrix) # определитель

np.linalg.matrix_rank(matrix) # ранк

eigenvalues, eigenvectors = np.linalg.eig(matrix) # собственные числа и векторы 
print(eigenvalues)
print()
print(eigenvectors)

# ## Доп возможности

np.info(np.eye)

np.loadtxt('file.txt') # загрузка из текстовог офайла 
np.genfromtxt('file.csv',delimiter=',') # загрузка из csv офайла 
np.savetxt('file.txt',arr,delimiter=' ') # запись в  текстовый файл 
np.savetxt('file.csv',arr,delimiter=',') # запись в  csv файл 

# ## Полезные ссылки

# https://www.dataquest.io/blog/numpy-cheat-sheet/
#     
# https://vk.com/doc114954319_556487793?hash=a4aeb3c8f00331ca46&dl=ce3a2e019cd32c83ee
#     
# https://towardsdatascience.com/numpy-cheat-sheet-4e3858d0ff0e

StarcoderdataJupyterScriptsDedupFiltered