# pip install numpy
# np : 관례적인 nimpy 별명
import numpy as np
# 파이썬의 list 값을 ndarray로 변환
array1 = np.array([1, 2, 3])
print('array1 type:', type(array1))
print('array1 array 형태:', array1.shape) # (3,) : 3행 배열을 의미
array2 = np.array([[1, 2, 3],
[2, 3, 4]])
print('array2 type:', type(array2))
print('array2 array 형태:', array2.shape) # (2, 3) : 2행, 3열 배열을 의미
array3 = np.array([[1, 2, 3]])
print('array3 type:', type(array3))
print('array3 array 형태:', array3.shape) # (1, 3) : 1행 3열 배열을 의미
# 차원 확인 : ndim
print('array1: {:0}차원, array2: {:1}차원, array3: {:2}차원'.format(array1.ndim, array2.ndim, array3.ndim))
list1 = [1, 2, 3]
print(type(list1))
array1 = np.array(list1)
print(type(array1))
print(array1, array1.dtype)
list2 = [1, 2, 'test']
array2 = np.array(list2)
print(array2, array2.dtype)
list3 = [1, 2, 3.0]
array3 = np.array(list3)
print(array3, array3.dtype)
# 파이썬의 range()
seq_array = np.arange(10)
print(seq_array)
print(seq_array.dtype, seq_array.shape)
# 0으로 초기화
zero_array = np.zeros((3, 2), dtype='int32')
print(zero_array)
print(zero_array.dtype, zero_array.shape)
# 1. dmfh chrlghk
one_array = np.ones((3, 2))
print(one_array)
print(one_array.dtype, one_array.shape)
array1 = np.arange(10)
print('array1:\n', array1)
array2 = array1.reshape(2, 5)
print('array2:\n', array2)
array3 = array1.reshape(5, 2)
print('array3:\n', array3)
# 10개로 만들 수 없는 사이즈는 오류 발생
# array4 = array1.reshape(4, 3) # 4,3 은 12개의 데이터가 필요
# -1 사용 시 가능한 개수를 자동으로 생성
array1 = np.arange(10)
print(array1)
array2 = array1.reshape(-1, 5)
print("array2 shape:", array2.shape)
array3 = array1.reshape(5, -1)
print('array3 shape:', array3.shape)
# -1을 사용해도 불가능한 사이즈는 오류 발생
array1 = np.arange(10)
# array4 = array1.reshape(-1, 4)
array1 = np.arange(8)
array3d = array1.reshape((2, 2, 2)) # 3차원
#a, b, c b x c 가 a개 있는 행렬
print('array3d: \n', array3d.tolist())
# 3차원 ndarray를 2차원 ndarray롭 변환
array5 = array3d.reshape(-1, 1)
print('array5: \n', array5.tolist())
print('array5 shape:', array5.shape)
# 1차원 ndarray를 2차원 ndarray로 변환
array6 = array1.reshape(-1, 1)
print('array6: \n', array6.tolist())
print('array56 shape:', array6.shape)
# 1부터 9까지의 1차원 ndarray 생성
array1 = np.arange(start=1, stop=10)
print('array1', array1)
# index는 0부터 시작하기에 array1[2]는 세 번째 index 위치의 데이터 값을 의미 = 3
value = array1[2]
print('value:', value)
print(type(value))
print('맨 뒤의 값:', array1[-1])
print('맨 뒤에서 두번째 값:', array1[-2])
# 값 치환
array1[0] = 9
array1[8] = 0
print('array1:', array1)
# 2차원
array1d = np.arange(start=1, stop=10)
array2d = array1d.reshape(3, 3)
print(array2d)
print('(row=0, col=0) index 가리키는 값', array2d[0, 0])
print('(row=0, col=1) index 가리키는 값', array2d[0, 1])
print('(row=1, col=0) index 가리키는 값', array2d[1, 0])
print('(row=2, col=2) index 가리키는 값', array2d[2, 2])
array1 = np.arange(start=1, stop=10)
array3 = array1[0:3]
print(array3)
print(type(array3))
array4 = array1[:3]
print(array4)
array5 = array1[3:]
print(array5)
# 값 복사
array6 = array1[:]
print(array6)
array1d = np.arange(start=1, stop=10)
array2d = array1d.reshape(3,3)
print('array2d:\n', array2d)
print('array2d[0:2, 0:2]: \n', array2d[0:2, 0:2])
print('array2d[1:3, 0:3]: \n', array2d[1:3, 0:3])
print('array2d[1:3, :] \n', array2d[1:3, :])
print('array2d[:, :] \n', array2d[:, :])
print('array2d[:2, 1:] \n', array2d[:2, 1:])
print('array2d[:2, 0] \n', array2d[:2, 0])
array1d = np.arange(start=1, stop=10)
array2d = array1d.reshape(3,3)
print('array2d:', array2d.tolist())
array3 = array2d[[0,1], 2]
print('array2d([0,1], 2):', array3.tolist())
array4 = array2d[[0,1], 0:2]
print('array2d([0,1], 0:2):', array4.tolist())
array5 = array2d[[0,1]]
print('array2d([0,1]):', array5.tolist())
array1d = np.arange(start=1, stop=10)
array3 = array1d[array1d > 5]
print('array1d > 5 boolean 인덱싱 값 결과:', array3)
array1d > 5
boolean_indexes = np.array([False, False, False, False, False, True, True, True, True])
array3 = array1d[boolean_indexes]
print('boolean 인덱스 필터링 결과:', array3)
indexes = np.array([5, 6, 7, 8])
array4 = array1d[indexes]
print('일반 인덱스 필터링 결과:', array4)
org_array = np.array([3, 1, 9, 5])
print('원본:', org_array)
# np.sort() 정렬
sort_array1 = np.sort(org_array)
print('np.sort() 호출 후 반환된 정렬 행렬:', sort_array1)
print('np.sort() 호출 후 원본 행렬:', org_array)
# ndarray.sort() 정렬 : 리턴 값이 반환되지 않고 기존 원본 행렬을 정렬
sort_array2 = org_array.sort()
print('org_array.sort() 호출 후 반환된 정렬 행렬:', sort_array2)
print('org_array.sort() 호출 후 원본 행렬:', org_array)
# 내림차순
org_array = np.array([3, 1, 9, 5])
sort_array1_desc = np.sort(org_array)[::1]
print('내리차순으로 정렬:', sort_array1_desc)
array2d = np.array([[8, 12],
[7, 1]])
print('기본:\n', array2d)
sort_array2d_axis0 = np.sort(array2d, axis=0) # axis=0 : 로우(행) 방향
print('로우 방향으로 정렬:\n', sort_array2d_axis0)
sort_array2d_axis1 = np.sort(array2d, axis=1) # axis=1 : 칼럼(열) 방향
print('칼럼 방향으로 정렬:\n', sort_array2d_axis1)
# argsort
# 정렬 행렬의 인덱스(위치)를 반환
org_array = np.array([3, 1, 9, 5])
sort_indices = np.argsort(org_array)
print(type(sort_indices))
print('행렬 정렬 시 원본 행렬의 인덱스:', sort_indices)
# 내림차순
org_array = np.array([3, 1, 9, 5])
sort_indices_desc = np.argsort(org_array)[::-1]
print('행렬 내림차순 정렬 시 원본 행렬의 인덱스:', sort_indices_desc)
name_array = np.array(['John', 'Mike', 'Sarah', 'Kate', 'Samuel'])
score_array = np.array([78, 95, 84, 98, 88])
# 성적을 오름차순으로 인덱스 정렬
sort_indices_asc = np.argsort(score_array)
print('성적 오름차순 정렬 시 score_array의 인덱스 :', sort_indices_asc)
# 정렬한 인덱스를 기반으로 이름 출력 : 성적이 낮은 학생 순서로 정렬해서 출력
print('성적 오름차순으로 name_array의 이름 출력 : ', name_array[sort_indices_asc])
# 행렬 내적 - np.dot()
A = np.array([[1, 2, 3],
[4, 5, 6]])
B = np.array([[7, 8],
[9, 10],
[11, 12]])
dot_product = np.dot(A, B)
print('행렬 내적 결과:\n', dot_product)
# 1*7 + 2*9 + 3*11 = 56 1*8 + 2*10 + 3*12 = 64 [[58 64]
# 4*7 + 5*9 + 6*11 = 138 4*8 + 5*10 + 6*12 = 154 [139 154]]
# 전치행렬 transpose() : 원행렬에서 행과 열의 위치를 교환
A = np.array([[1, 2],
[3, 4]])
transpose_mat = np.transpose(A)
print('A의 전치 행렬:\n', transpose_mat)
# 역행렬 np.linalg.lav() : 내적의 곱으로 단위행렬이 나오는 행렬
a = np.array(range(4)).reshape(2, 2) # 1차원 0부터 3까지의 데이터를 2차원으로 변환
a
a_inv = np.linalg.inv(a)
a_inv
a.dot(a_inv)