다차원 배열 제공(ndarray 클래스)
- 배열의 특징
=> 동일한 자료형을 가지는 값들이 배열 형태로 존재함
=> N차원의 형태로 구성이 가능함
=> 데이터 접근을 최적화 하기 위해서 색인(index)을 부여
numpy 데이터타입(형태) 종류
배열 생성
1차원 배열 생성
lst1 = [1, 2, 3, 4, 5] # 리스트
lst1
# [1, 2, 3, 4, 5]
import numpy as np
arr1 = np.array(lst1) # np.array() => 배열을 생서해주는 함수
arr1
# array([1, 2, 3, 4, 5])
2차원 배열 생성
arr2 = np.array([[1, 2, 3], [4, 5, 6]])
arr2
# array([[1, 2, 3],
# [4, 5, 6]])
타입을 지정하여 배열 생성
arr3 = np.array([1.2, 2.3, 3.4, 4.5], dtype = np.int64)
arr3
# array([1, 2, 3, 4], dtype=int64)
타입 변경하기
arr3_type = arr3.astype(np.float64)
arr3_type
# array([1., 2., 3., 4.])
arr3_type.dtype
# 파이썬 기초 타입확인 ==> type(변수명)
# Numpy 타입확인 ==> 변수명.dtype
# dtype('float64')
배열변수 사용해보기
- 배열의 크기 확인 : shape
- 배열의 차원 확인 : ndim
- 배열 전체 요소의 개수 확인 : size
- 배열 데이터 타입 확인 : dtype
# shape
print("배열의 크기 : ", arr1.shape)
print("배열의 크기 : ", arr2.shape)
# 배열의 크기 : (5,)
# 배열의 크기 : (2, 3)
# ndim (number of dimension)
print(arr1)
print("배열의 차원 : ", arr1.ndim)
# [1 2 3 4 5]
# 배열의 차원 : 1
print(arr2)
print("배열의 차원 : ", arr2.ndim)
# [[1 2 3]
# [4 5 6]]
# 배열의 차원 : 2
# size
print(arr1)
print("전체 요소의 갯수 : ", arr1.size)
# [1 2 3 4 5]
# 전체 요소의 갯수 : 5
# dtype
print(arr1)
print("배열의 타입 : ", arr1.dtype)
# [1 2 3 4 5]
배열의 타입 : int32
print(arr2)
print("배열의 타입 : ", arr2.dtype)
# [[1 2 3]
# [4 5 6]]
# 배열의 타입 : int32
1 ~ 50 까지 숫자가 담긴 배열의 생성
lst = []
for i in range(1, 51) :
lst.append(i)
print(lst)
# [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50]
np.array(lst)
# array([ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17,
# 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34,
# 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50])
np.arange(시작값, 끝값+1, 증감값)
=> 끝값을 포함하고 싶을 때 항상 +1을 해줘야 함.
=> 1차원으로만 생성
arr4 = np.arange(1, 51)
arr4
# array([ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17,
# 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34,
# 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50])
# 1 ~ 50 까지의 숫자 중 10씩 증가한 값의 배열
np.arange(1, 51, 10)
# array([ 1, 11, 21, 31, 41])
# 1 ~ 50을 담은 2차원 배열 생성
rearr1 = np.arange(1, 51).reshape(5, 10) # reshape(행, 열)
rearr1
# array([[ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10],
# [11, 12, 13, 14, 15, 16, 17, 18, 19, 20],
# [21, 22, 23, 24, 25, 26, 27, 28, 29, 30],
# [31, 32, 33, 34, 35, 36, 37, 38, 39, 40],
# [41, 42, 43, 44, 45, 46, 47, 48, 49, 50]])
랜덤값 배열 생성
np.random.randint(1, 25) # 1 ~ 25까지 1가지 수를 생성
arr_ran1 = np.random.randint(2, 10, size=(2, 3)) # 2 ~ 10까지 (2행 3열 2차원 배열)
arr_ran1
배열의 연산
배열 요소별 연산
arr5 = np.arange(2, 10, 2)
print(arr5)
print(arr5/2)
print(arr5+2)
# [2 4 6 8]
# [1. 2. 3. 4.]
# [ 4 6 8 10]
# list였을 때는, 배열 요소별 연산이 불가
[2, 4, 6, 8] / [2]
# TypeError: unsupported operand type(s) for /: 'list' and 'list'
Broadcasting
arr_n = np.arange(2, 10)
arr_n + 2 # 차원이 다른 연산이 가능하도록 하는 기능 => Broadcasting
# array([ 4, 5, 6, 7, 8, 9, 10, 11])
배열 간 연산
arr1
# array([1, 2, 3, 4, 5])
arr1 + arr1 # 위치적으로 대응되는 데이터에 대해 연산 수행
# array([ 2, 4, 6, 8, 10])
arr1*arr1
# array([ 1, 4, 9, 16, 25])
1차원 배열 연산
arr_a = np.array([1, 2, 3])
arr_b = np.array([4, 5, 6])
arr_a + arr_b
# array([5, 7, 9])
2차원 배열 연산
arr_a2 = np.array([[7, 8, 9], [10, 11, 12]])
arr_b2 = np.array([[13, 14, 15], [16, 17, 18]])
arr_b2 - arr_a2
# array([[6, 6, 6],
# [6, 6, 6]])
# Broadcasting
arr_a2 + 3
# array([[10, 11, 12],
# [13, 14, 15]])
데이터 접근
- indexing, slicing : 인덱스 기반으로 데이터 접근
1차원 배열의 인덱싱
arr1 = np.arange(11) # 0 ~ 10까지의 1차원 배열 생성
arr1
# array([ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10])
# 5라는 데이터에 접근하기
arr1[5]
# 5
# 1, 4, 8 데이터 접근하기
arr1[[1, 4, 8]]
# array([1, 4, 8])
# 3 ~ 7 데이터 접근하기
arr1[3:8]
# array([3, 4, 5, 6, 7])
arr1[3:8] = 12
# 슬라이싱 후 12라는 값으로 배열 값이 변경
# list에서는 슬라이싱으로 접근해서 값을 하나만 넣어줄 경우 리스트 길이가 변경됨
# 넘파이 배열에서는 슬라이싱으로 접근한 데이터 값이 새로운 값으로 대체
arr1
# array([ 0, 1, 2, 12, 12, 12, 12, 12, 8, 9, 10])
2차원 배열의 인덱싱
arr2 = np.arange(30).reshape(5, 6) # 0 ~ 29까지 5행 6열의 2차원 배열로 생성
arr2
# array([[ 0, 1, 2, 3, 4, 5],
# [ 6, 7, 8, 9, 10, 11],
# [12, 13, 14, 15, 16, 17],
# [18, 19, 20, 21, 22, 23],
# [24, 25, 26, 27, 28, 29]])
# 2행에 접근하기
arr2[1]
# array([ 6, 7, 8, 9, 10, 11])
# 9 데이터 접근
arr2[1][3]
# 9
2차원 데이터 접근
=> 배열명[행][열]
=> 배열명[행, 열]
=> 배열명[시작행 : 끝행, 시작열 : 끝열]
=> 배열명[행, [0, 3, 5]]
arr2
# array([[ 0, 1, 2, 3, 4, 5],
# [ 6, 7, 8, 9, 10, 11],
# [12, 13, 14, 15, 16, 17],
# [18, 19, 20, 21, 22, 23],
# [24, 25, 26, 27, 28, 29]])
# 2차원 슬라이싱
# 행 : 2번째 행까지, 열 : 1 ~ 3까지 출력
arr2[:2, 1:4]
# array([[1, 2, 3],
# [7, 8, 9]])
# 14, 21 출력
arr2[[2, 3], [2, 3]]
# array([14, 21])
# 27, 28 데이터에 접근
arr2[4, 3:5]
arr2[4, [3, 4]]
# array([27, 28])
# 12, 18, 15, 21 ==> 2차원 배열형태로 가져오기
arr2[2:4, [0, 3]]
arr2[2:4, ::3]
# array([[12, 15],
# [18, 21]])
Boolean 인덱싱(색인)
- 논리연산자를 활용하여 True, False 결과를 출력
- True에 해당하는 데이터에 접근
- 특정 기준에 의해 데이터에 접근하고자 할 때 사용
# 8개의 난수 값을 갖는 1차원 배열 생성
# seed(3) : 메르센-트위스터 알고리즘(624개 모두 세트)에서 난수를 뽑아오기 위한 설정 값
# 0 ~ 가능, seed값이 같으면 랜덤 수도 동일
np.random.seed(3)
score = np.array(np.random.randint(50, 100, size=8))
score
# array([92, 74, 53, 58, 50, 71, 69, 60])
# 70점 이상인 성적을 확인
score >= 70
# array([ True, True, False, False, False, True, False, False])
# 논리값으로 마스킹하고 원하는 값만 출력
score[score>=70]
# array([92, 74, 71])
# 70점 미만인 데이터는 몇 개 일까?
score[score<70].size
# 5
name = np.array(['수하', '은지', '선제', '재윤', '현준', '하원', '다빈', '승광'])
name
# array(['수하', '은지', '선제', '재윤', '현준', '하원', '다빈', '승광'], dtype='<U2')
# 70점 이상인 사람의 이름을 확인
name[score >= 70]
# array(['수하', '은지', '하원'], dtype='<U2')
# 70점 미만인 사람의 이름 확인
name[score<70]
# array(['선제', '재윤', '현준', '다빈', '승광'], dtype='<U2')
import pickle
data = np.loadtxt('data/height_weight.txt', delimiter = ',')
data
# array([[175.2, 180.3, 175. , 169.2, 185.2, 188. , 177.6, 178.2, 177. ,
# 179. ],
# [ 65.6, 88. , 79.2, 69.3, 55. , 71.2, 73. , 68.9, 74. ,
# 82. ]])
height = data[0]*0.1
# array([1.752, 1.803, 1.75 , 1.692, 1.852, 1.88 , 1.776, 1.782, 1.77 ,
# 1.79 ])
weight = data[1]
# array([65.6, 88. , 79.2, 69.3, 55. , 71.2, 73. , 68.9, 74. , 82. ])
bmi = weight / height**2
# array([21.37153104, 27.07018468, 25.86122449, 24.20652885, 16.03543423,
# 20.14486193, 23.14392095, 21.69720651, 23.62028791, 25.59220998])
# 비트연산자 : &(and) 와 |(or)로 표현해줘야 함!! 안그러면 오류!!
bmi[(bmi >= 23)&(bmi < 25)].size
# 3
데이터 수정
arr2
# array([[ 0, 1, 2, 3, 4, 5],
# [ 6, 7, 8, 9, 10, 11],
# [12, 13, 14, 15, 16, 17],
# [18, 19, 20, 21, 22, 23],
# [24, 25, 26, 27, 28, 29]])
arr2[:, ::2] = 7
# 위치 접근 ==> 7이라는 값을 대입(초기화)
arr2
# array([[ 7, 1, 7, 3, 7, 5],
# [ 7, 7, 7, 9, 7, 11],
# [ 7, 13, 7, 15, 7, 17],
# [ 7, 19, 7, 21, 7, 23],
# [ 7, 25, 7, 27, 7, 29]])
넘파이 유용한 함수
합계를 구하는 함수 : sum()
arr2.sum() # 파이썬 기초의 sum() 연결
np.sum(arr2)
# 330
평균을 구하는 함수 : mean()
arr2.mean() # 파이썬 기초의 mean() 연결
np.mean(arr2)
# 11.0
제곱근을 구하는 함수 : sqrt()
np.sqrt(arr2)
# array([[2.64575131, 1. , 2.64575131, 1.73205081, 2.64575131,
# 2.23606798],
# [2.64575131, 2.64575131, 2.64575131, 3. , 2.64575131,
# 3.31662479],
# [2.64575131, 3.60555128, 2.64575131, 3.87298335, 2.64575131,
# 4.12310563],
# [2.64575131, 4.35889894, 2.64575131, 4.58257569, 2.64575131,
# 4.79583152],
# [2.64575131, 5. , 2.64575131, 5.19615242, 2.64575131,
# 5.38516481]])
절댓값을 구하는 함수 : abs()
arr12 = np.array([-1, 2, 3, -4, -5])
arr12
# array([-1, 2, 3, -4, -5])
np.abs(arr12)
# array([1, 2, 3, 4, 5])
댓글