1. 배열 및 인덱싱
01. ndarray 생성
(1) 리스트로부터 생성
# 리스트로부터 생성
import numpy as np
arr = np.array([1, 2, 3, 4])
print(arr)
(2) n으로 채운 배열
# 0으로 채운 배열 생성
arr = np.zeros((2, 3)) # 2x3 배열
print(arr)
# 1로 채운 배열 생성
arr = np.ones((3, 2)) # 3x2 배열
print(arr)
(3) 수열을 가진 배열
# 연속적인 값으로 배열 생성
arr = np.arange(0, 10, 2) # 0부터 9까지 2씩 증가하는 값
print(arr)
# 등간격으로 배열 생성
arr = np.linspace(0, 1, 5) # 0에서 1까지 5개의 등간격 값
print(arr)
# 지수 | 로그로 배열 생성
arr = np.logspace(1, 3, 4) # a의 1제곱이 10, a의 3제곱이 1000이므로, base를 주지 않으면 default 값이 10 이라는 것을 알 수 있다.(기본적인 상용로그값)
print(arr)
[참고] 지수 | 로그
- 지수 : 거듭제곱 $a^x=b$에서 x
- 밑 : 거듭제곱될 수 $a^x=b$에서 a
- 로그 : 밑과 거듭제곱 결과로부터 지수를 반환 $log_a{b} = x$
- 자연로그 : 밑이 자연상수e (2.718...)인 로그
- 상용로그 : 밑이 10인 로그
(4) 정규분포를 따른 배열
# 정규분포로 난수 배열 생성
arr = np.random.randn(2, 3) # 2x3 배열
print(arr)
02. ndarray 형변환
형변환
# 형변환
arr = np.array([1.234, 5.678, 9, 10]) # 묵시적 형 변환
arr = np.array([1.234, 5.678, 9, 10], dtype = float) # 명시적 형 변환
arr = np.array([1.234, 5.678, 9, 10], dtype = int) # float -> int 형 변환은 소숫점은 그대로 버림
arr, arr.dtype
arr = np.array([1.234, 5.678, 9, 10])
arr = arr.astype(int) # astype : 자료형 변환
arr, arr.dtype
[출력]
(array([ 1, 5, 9, 10]), dtype('int64'))
03. ndarray 인덱싱
(1) slicing은 차원을 유지해준다
print(arr[:-1, 0:1], arr[:-1, 0:1].shape) # 슬라이싱 = 차원 유지
print(arr[:-1, 0], arr[:-1, 0].shape) # 인덱스로 접근하면 값을 꺼내서 반환하기 때문에 차원이 제거된다.
[출력]
[[10]
[40]] (2, 1)
[10 40] (2,)
(2) fancy indexing
1차원 배열 fanct indexing
arr = np.arange(5,31,5)
print(arr)
print(arr[[1, 3, 5]])
indices = [1, 3, 5]
print(arr[indices])
[출력]
[ 5 10 15 20 25 30]
[10 20 30]
[10 20 30]
2차원 배열 fancy indexing
arr = np.array([
[5, 10, 15, 20],
[25, 30, 35, 40],
[45, 50, 55, 60]
])
# 찾고 싶은 인덱스 = [10 35]
indices1 = [0,1]
indices2 = [1,2]
print(arr[indices1,indices2])
print(arr[[0,1],[1,2]])
[출력]
[10 35]
[10 35]
(3) boolean indexing
1차원 배열 boolean indexing
arr = np.arange(1,6)
print(arr)
bools = [True, False, False, False, True]
print(arr[bools])
[출력]
[1 2 3 4 5]
[1 5]
2차원 배열 boolean indexing
arr = np.array([
[3, 6, 9],
[12, 15, 18],
[21, 24, 27]
])
print(arr[arr > 10])
print(arr[arr % 2 == 0])
[출력] # 조건에 맞는 배열을 출력할 수 있다
[12 15 18 21 24 27]
[ 6 12 18 24]
(4) 조건 반환
np.all() : ndarray의 모든 요소가 조건을 만족할 때 True 반환
arr = np.array([10, 20, 30, 40, -50])
is_all_positive = np.all(arr>0)
if is_all_positive:
print('모든 수는 양수입니다')
else:
print('모든 수가 양수는 아닙니다.')
[출력]
모든 수가 양수는 아닙니다
np.any() : ndarray의 요소가 조건을 하나라도 만족할 때 True 반환
arr = np.array([10, 20, 30, 40, -50])
has_positive = np.any(arr>0)
if has_positive:
print('양수가 포함되어 있습니다다')
else:
print('모든 수가 양수입니다.')
[출력]
양수가 포함되어 있습니다
2. numpy 연산
01. Dot Product 연산
💡점곱연산 (Dot Product / 내적)
- 두 행렬 A, B의 곱셈은 첫 번째 행렬 A의 행과 두 번째 행렬 B열 간의 곱셈을 수행한다.
- 첫 번째 행렬 A의 열의 수와 두 번째 행렬 B의 행의 수가 같아야 한다.
- 연산 결과의 shape은 (첫 번째 행렬 A의 행수, 두 번째 행렬 B의 열수) 이다.
arr3 = np.array([[1, 2, 3],[4, 5, 6]]) #(2,3)
arr4 = np.array([[7, 8],[9, 10],[11, 12]]) #(3,2)
arr3.shape, arr4.shape # arr3과 arr4가 내적되었을 떄 shape을 상상해보자. arr3의 행, arr4의 열이 나올 것이다
print(np.dot(arr3,arr4).shape)
print(np.dot(arr4,arr3).shape)
[출력]
(2, 2)
(3, 3)
[[ 7 8]
[ 9 10]
[11 12]]
[[1 2 3]
[4 5 6]]
🤔 만약 배열의 순서를 바꾼다면?
# print(arr4) # (3, 2)
# print(arr3) # (2, 3) 이렇게 되니까 arr4의 행, arr3의 열을 따와서 둘의 내적은 (3, 3) 이 된다.
02. broadcasting 연산
arr_a = np.arange(1,10).reshape(3,3)
result_arr = arr_a * np.array([[5, 5, 5],[5, 5, 5],[5, 5, 5]]) # (3, 3)
result_arr = arr_a * np.array([5, 5, 5]) # (3, )
result_arr = arr_a * np.array([5]) # (1, )
result_arr = arr_a * 5 # 스칼라값
result_arr
[출력]
array([[ 5, 10, 15],
[20, 25, 30],
[35, 40, 45]])
3,3 배열인 arr_a과 같은 요소값을 가진 여러 배열들을 곱한 결과 모두 같은 값이 출력된다.
이는 numpy의 broadcating 연산 때문이다.
⭐ 2차원과 1차원의 연산을 고려해보자
- 두 배열이 shape이 다르면 broadcating 연산을 수행한다
- shape이 작은 쪽에서 큰 쪽에 맞춰 확장한다
- 두 배열의 행 또는 열이 일치해야 확장 가능하다
- 크기가 1인 경우 무조건 확장 가능하다
- shape이 다른 경우 마지막 축부터 차원이 동일한지 비교한다
- 1차원이 자신보다 큰 차원을 만나면 요소의 개수를 맞춰주기 위해 확장된다!!!! (작은쪽에서 큰 쪽으로 확장)
arr1 = np.array([[1, 2, 3], [4, 5, 6]]) # (2, 3)
arr2 = np.array([5, 10, 15]) # (3, )
print(arr1)
print(arr2)
arr1 + arr2
[출력]
[[1 2 3]
[4 5 6]] # arr1
[ 5 10 15] # arr2
array([[ 6, 12, 18], # arr1 + arr2
[ 9, 15, 21]])
1차원인 arr2는 arr1에 맞춰 확장된다.
이렇게 배열은 작은 차원에서 큰 차원으로 수를 확장시킨다.
한 예시를 더 보자
arr1 = np.array([1, 2, 3]) # (3,)
arr2 = np.array([[4], [5], [6]]) # (3,1)
arr1.shape, arr2.shape
print(arr1)
print(arr2)
arr1 + arr2
[출력]
[1 2 3] #arr1
[[4] #arr2
[5] #arr2
[6]] #arr2
array([[5, 6, 7],
[6, 7, 8],
[7, 8, 9]]) # arr1 + arr2
요소가 적은 arr2가 arr1을 맞춰 np.array([[4, 4, 4], [5, 5, 5], [6, 6, 6]]) 형태로 확장한 구조이다.
<!-------------- 에러코드!!!!!!!!!!!!!!!! ---------------!>
arr1 = np.array([[1, 2, 3],[1, 2, 3]]) # (2, 3)
arr2 = np.array([1, 2]) # (2, )
그러나, 행과 열이 일치하지 않을 경우 arr2가 [1,2], [1,2]로 확장이 되더라도 요소가 없어서 확장하지 못한다.
03. 집계함수
올림 반올림 (ceil, round)
arr_float = np.array([[1.234, 5.678],[7.89, 10.123]])
print(np.ceil(arr_float)) # 올림
print(np.round(arr_float)) # 반올림
print(np.round(arr_float, 2)) # 두 번째 인자는 소숫점을 어디까지 표시할것인지다
[출력]
[[ 2. 6.]
[ 8. 11.]]
[[ 1. 6.]
[ 8. 10.]]
[[ 1.23 5.68]
[ 7.89 10.12]]
내림 절삭 (floor, trunc)
arr_float = np.array([[1.234, -5.678],[-7.89, 10.123]])
print(np.floor(arr_float))
print(np.trunc(arr_float))
[출력]
[[ 1. -6.]
[-8. 10.]]
[[ 1. -5.]
[-7. 10.]]
'SKN > 04. Data Analysis' 카테고리의 다른 글
| 05. matplotlib (0) | 2025.03.06 |
|---|---|
| 04. 데이터 결측치 확인 (0) | 2025.03.06 |
| 03. pandas overview (0) | 2025.03.04 |
| 02. numpy [통계] [정렬] [병합] (0) | 2025.02.28 |