- 배열의 원소 조회 및 변경
인덱싱과 슬라이싱을 이용한 배열의 원소 조회 및 변경
배열 인덱싱(Indexing)
- index
- 배열내의 원소의 식별번호
- 0부터 시작
- indexing
– index를 이용해 원소 조회
- [] 표기법 사용
- 구문
- ndarray[index]
- 양수는 지정한 index의 값을 조회한다.
- 음수는 뒤부터 조회한다.
- 마지막 index가 -1
- 2차원배열의 경우
- arr[0축 index, 1축 index]
- 파이썬 리스트와 차이점
- N차원 배열의 경우
- arr[0축 index, 1축 index, …, n축 index]
- 팬시(fancy) 인덱싱
- 여러개의 원소를 한번에 조회할 경우 리스트에 담아 전달한다.
- 다차원 배열의 경우 각 축별로 list로 지정
arr[[1,2,3,4,5]]
- 1차원 배열(vector): 1,2,3,4,5 번 index의 원소들 한번에 조회
arr[[0,3], [1,4]]
- [0,3] - 1번축 index list, [1,4] - 2번축 index list
- 2차원 배열(matrix): [0,1], [3,4] 의 원소들 조회
import numpy as np
a = np.arange(30)
a.shape
a
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])
**1. 조회.**
a[1]
1
**2. 여러 index들의 값 조회 -> fancy indexing => index들을 리스트로 묶어서 전달.**
a[[1,3,2,7]]
array([1, 3, 2, 7])
**3. 변경.**
a[1] = 1000
a
array([ 0, 1000, 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])
**4. 일괄변경**
a[[2, 4, 5]] = 5000
a
array([ 0, 1000, 5000, 3, 5000, 5000, 6, 7, 8, 9, 10,
11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21,
22, 23, 24, 25, 26, 27, 28, 29])
a[[8, 9, 10]] = 8000, 9000, 10000
a
array([ 0, 1000, 5000, 3, 5000, 5000, 6, 7, 8000,
9000, 10000, 11, 12, 13, 14, 15, 16, 17,
18, 19, 20, 21, 22, 23, 24, 25, 26,
27, 28, 29])
**5. ( 30 , ) 1차원배열을 ( 5 , 6 ) 2차원배열로 reshape.**
- size만 동일하면 reshape 가능!!!!
a2 = np.arange(30).reshape(5, 6)
a2
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]])
a2[0] # 0축의 index 0을 조회
a2[0,3] # a[axis0, axis1]
a2[-1,-1]
29
**6. Fancy indexing 으로 조회.**
a2[0, 2]
a2[3, 4]
22
a2[[0,3], [2,4]]
array([ 2, 22])
- **[ 0 , 2 ] 와 [ 3 , 4 ]를 조회한 것이다.**
a3 = np.arange(12).reshape(2, 2, 3)
a3
array([[[ 0, 1, 2],
[ 3, 4, 5]],
[[ 6, 7, 8],
[ 9, 10, 11]]])
a3[0,1,1]
a3[1,1,2]
11
a3[[0,1],[1,1],[1,2]]
array([ 4, 11])
슬라이싱
- 배열의 원소들을 범위로 조회한다.
- ndarry[start : stop : step ]
- start : 시작 인덱스. 기본값 0
- stop : 끝 index. stop은 포함하지 않는다. 기본값 마지막 index
- step : 증감 간격. 기본값 1
다차원 배열 슬라이싱
- 각 축에 slicing 문법 적용
- 2차원의 경우
- arr [0축 slicing, 1축 slicing]
arr[:3, :]
,
로 축을 구분한 다중 슬라이싱 사용
- arr [0축 slicing, 1축 slicing]
- 다차원의 경우
- arr[0축 slicing, 1축 slicing, …, n축 slicing]
- slicing과 indexing 문법은 같이 쓸 수 있다.
슬라이싱은 원본에 대한 View
- slicing한 결과는 새로운 배열을 생성하는 것이 아니라 기존 배열을 참조한다.
- slicing한 배열의 원소를 변경하면 원본 배열의 것도 바뀐다.
- 배열.copy()
- 배열을 복사한 새로운 배열 생성
- 복사후 처리하면 원본이 바뀌지 않는다.
a = np.arange(30)
a
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])
1. ‘0 ~ 4’, step: - 1
a[:5]
array([0, 1, 2, 3, 4])
a[2:15:3]
array([ 2, 5, 8, 11, 14])
a[20:-1] # 마지막은 뺴고 조회
array([20, 21, 22, 23, 24, 25, 26, 27, 28])
a[:4] = 400
a
array([400, 400, 400, 400, 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. 원본은 바꾸고 싶지 않을때 ‘ .copy( ) ‘를 사용한다
b = a[:4].copy()
print(b)
print(b[0])
b[0] = 500000
b
[500 400 400 400]
500
array([500000, 400, 400, 400])
a2 = np.arange(30).reshape(5, 6)
a2
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]])
3. slicing 을 통해 범위설정 조회가 가능하다.
a2[:3, 1:5]
array([[ 1, 2, 3, 4],
[ 7, 8, 9, 10],
[13, 14, 15, 16]])
print(a2[:,1])
print('-'*20)
print(a2[:,[1,4]])
print('-'*20)
print(a2[1,1:5])
print('-'*20)
print(a2[[1,-1],1:5])
[ 1 7 13 19 25]
--------------------
[[ 1 4]
[ 7 10]
[13 16]
[19 22]
[25 28]]
--------------------
[ 7 8 9 10]
--------------------
[[ 7 8 9 10]
[25 26 27 28]]
boolean indexing
- Index 연산자에 같은 형태(shape)의 Boolean 배열을 넣으면 True인 index의 값만 조회 (False가 있는 index는 조회하지 않는다.)
- ndarray내의 원소 중에서 원하는 조건의 값들만 조회할 때 사용
- ndarray는 element-wise 연산을 지원한다. 이를 이용해 boolean indexing으로 원하는 조건의 값들을 조회할 수 있다.
- boolean indexing을 masking이라고도 한다.
넘파이 비교연산자
- 파이썬의 and, or, not은 사용할 수 없다.
&
: and연산|
: or 연산~
: not 연산- 피연산자는
( )
로 묶어야 한다.
np.random.seed(0)
a = np.random.randint(100, size = 20) # 0 ~ 99 사이의 임의 정수 20개.
a
array([44, 47, 64, 67, 67, 9, 83, 21, 36, 87, 70, 88, 88, 12, 58, 65, 39,
87, 46, 88])
1. a 에서 50 이상인 값들만 조회.
a[a > 50] # 원소별로 연산
array([64, 67, 67, 83, 87, 70, 88, 88, 58, 65, 87, 88])
2. ‘30 < a < 60’
a[(a > 30) & (a <60)]
array([44, 47, 36, 58, 39, 46])
3. 30 ~ 60 사이가 아닌것.( ‘ ~ ‘ 사용)
a[~((a > 30) & (a <60))]
array([64, 67, 67, 9, 83, 21, 87, 70, 88, 88, 12, 65, 87, 88])
a[(a <= 30) | (a >= 60)]
array([64, 67, 67, 9, 83, 21, 87, 70, 88, 88, 12, 65, 87, 88])
a2 = np.random.randint(100, size = (7,8))
a2
array([[82, 46, 99, 20, 81, 50, 27, 14],
[41, 58, 65, 36, 10, 86, 43, 11],
[ 2, 51, 80, 32, 54, 0, 38, 19],
[46, 42, 56, 60, 77, 30, 24, 2],
[ 3, 94, 98, 13, 40, 72, 19, 95],
[72, 26, 66, 52, 67, 61, 14, 96],
[ 4, 67, 11, 86, 77, 75, 56, 16]])
(a2 > 50).shape
(7, 8)
4. 다차원의 배열을 boolen indexing 을 하게되면 결과는 조건을 충족하는 값들로 1차원으로 반환한다.
a2[a2 > 50]
array([82, 99, 81, 58, 65, 86, 51, 80, 54, 56, 60, 77, 94, 98, 72, 95, 72,
66, 52, 67, 61, 96, 67, 86, 77, 75, 56])
np.where()
- True의 index 조회
- np.where(boolean 배열) - True인 index를 반환
- 반환타입: Tuple . True인 index들을 담은 ndarray를 축별로 Tuple에 묶어서 반환한다.
- boolean연산과 같이사용하여 배열내에 특정 조건을 만족하는 값들을 index(위치)를 조회할 때 사용한다.
- np.where(boolean 배열) - True인 index를 반환
- True와 False를 다른 값으로 변환
- np.where(boolean 배열, True를 대체할 값, False를 대체할 값)
- 배열내의 True를 True를 대체할 값으로 False를 False를 대체할 값 으로 변환한다.
- np.where(boolean 배열, True를 대체할 값, False를 대체할 값)
r = np.where([True, False, True])
print(type(r), type(r[0]))
r
<class 'tuple'> <class 'numpy.ndarray'>
(array([0, 2]),)
1. 특정한 값으로 변환해서 출력한다.
r2 = np.where([True, False, True], '참', '거짓')
r2
array(['참', '거짓', '참'], dtype='<U2')
l = [
[True, False, True],
[False, False, True]
]
r3 = np.where(l)
r3 # [0,0],[0,2],[1,2]
(array([0, 0, 1]), array([0, 2, 2]))
for a1, a2 in zip(r3[0], r3[1]):
print(a1, a2 ,sep = ', ')
0, 0
0, 2
1, 2
np.random.seed(0)
a2 = np.random.randint(100, size = (5, 2, 3))
a2.shape
(5, 2, 3)
2. Boolean Indexing.
- ( 5, 2, 3 )인 a2에서 70 이상인 값들 조회 ==> 조건이 True값들을 조회 ==> boolean indexing
a2[a2 >= 70]
array([83, 87, 70, 88, 88, 87, 88, 81, 77, 72, 80, 79])
3. np.where( )
- 70 이상인 값들의 위치. == > 조건이 True인 값들의 위치(index) ====> np.where()
axis1, axis2, axis3 = np.where(a2 >= 70)
print(axis1)
print(axis2)
print(axis3)
[1 1 1 1 2 2 3 3 3 4 4 4]
[0 1 1 1 0 1 0 0 1 0 1 1]
[0 0 1 2 0 2 1 2 2 0 0 2]
for i, j, k in zip(axis1, axis2, axis3):
print(a2[i, j, k], end = ', ')
83, 87, 70, 88, 88, 87, 88, 81, 77, 72, 80, 79,
기타
- np.any(boolean 배열)
- 배열에 True가 하나라도 있으면 True 반환
- 배열내에 특정조건을 만족하는 값이 하나 이상 있는지 확인할 때 사용
- np.all(boolean 배열)
- 배열의 모든 원소가 True이면 True 반환
- 배열내의 모든 원소가 특정 조건을 만족하는지 확인 할 때 사용
np.any([True, False, False, False])
True
np.any(a2 == 99) # 99가 하나라도 있나?
np.any(a2 == 83)
# np.where(a==99)
False
np.all([True, True, False])
np.all([True, True, True])
True
np.all(a2 > 0)
np.all(a2 > 10)
# np.where(a2 <= 10)
False
배열의 형태(shape) 변경
- 배열의 원소의 개수를 유지하는 상태에서 shape을 변경할 수있다.
- 예) (16, ) -> (4,4) -> (2,2,4) -> (2,2,2,2), -> (4,4,1) -> (1, 16)
reshape()을 이용한 차원 변경
numpy.reshape(a, newshape)
또는ndarray.reshape(newshape)
- a: 형태를 변경할 배열
- newshape : 변경할 형태 설정.
- 원소의 개수를 유지하는 shape으로만 변환 가능하다.
- 각 axis(축)의 size를 지정할 때 하나의 축의 size를 -1로 줄 수있다. 그러면
전체 size - 다른 축의 size합
을 -1로 지정한 axis 의 size로 지정한다.
- 둘다 원본을 바꾸지 않고 reshape한 새로운 배열을 만들어 반환한다.
- 내가 갖고있는 라이브러리의 차원과 가져다 쓰려고 하는 차원이 다를 경우
reshape 사용하여 차원을 맞추고 사용한다.
a = np.arange(20)
print(a.shape)
a
(20,)
array([ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
17, 18, 19])
r1 = np.reshape(a, (2, 10))
print(r1.shape)
r1
(2, 10)
array([[ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9],
[10, 11, 12, 13, 14, 15, 16, 17, 18, 19]])
r2 = a.reshape((4, 5)) # 튜플로 묶어서 입력.
r2 = a.reshape(4,5) # 가변인자로 입력 가능
print(r2.shape)
r2
(4, 5)
array([[ 0, 1, 2, 3, 4],
[ 5, 6, 7, 8, 9],
[10, 11, 12, 13, 14],
[15, 16, 17, 18, 19]])
r3 = a.reshape(2, 2, -1) # -1 은 너가 알아서 계산하라는 의미.
print(r3.shape)
r3
(2, 2, 5)
array([[[ 0, 1, 2, 3, 4],
[ 5, 6, 7, 8, 9]],
[[10, 11, 12, 13, 14],
[15, 16, 17, 18, 19]]])
차원 늘리기(확장)
- Dummy axis(축)을 늘린다.
- Dummy axis: size가 1인 axis 를 말한다.
-
reshape() 을 이용해 늘릴 수 있다.
- indexer와 np.newaxis 변수를 이용해 늘린다.
- ndarray[…, np.newaxis] 또는 ndarray[np.newaxis, …]
- 맨앞 또는 맨 마지막에 dummy axis(축)을 늘릴때 사용한다.
- 축을 늘리려는 위치에 np.newaxis를 지정하고
...
으로 원본 배열의 shape을 유지함을 알려준다.
- ndarray[…, np.newaxis] 또는 ndarray[np.newaxis, …]
+ a
- (5, 30) 30개의 속성을 가진 5 개수
- 차원 늘리기 시 중간 축을 늘릴 경우는 거의 없다.
a.shape
# (20,1)
r1 = a.reshape(20, 1)
r1 = a.reshape(-1, 1)
print(r1.shape)
# (1, 20)
r1 = a.reshape(1, -1)
r1.shape
(20, 1)
(1, 20)
a2.shape # 다차원
# (1, 5, 2, 3)
r2 = a2.reshape(1, 5, 2, -1) # reshape로 다차원에서는 일일이 다 입력해야 함으로 번거러움 쓸 필요 딱히 없음.
# (5, 2, 3, 1)
r2 = a2.reshape(5, 2, 3, 1)
r2.shape
(5, 2, 3, 1)
a.shape
# (20,1)
a[... , np.newaxis].shape
# (1, 20)
a[np.newaxis, ...].shape
(1, 20)
a2.shape
# (1, 5, 2, 3)
a2[np.newaxis, ...].shape
# (5, 2, 3, 1)
a2[..., np.newaxis].shape
(5, 2, 3, 1)
1. ( 5, 2, 3 )인 a2의 2번축에 dummy axis를 추가.
r = np.expand_dims(a2, axis = 2) #(5, 2, 3)인 a2의 2번축에 dummy axis를 추가.
r = np.expand_dims(a2, axis = 0)
r = np.expand_dims(a2, axis = -1)
r.shape
(1, 5, 2, 3)
차원 줄이기(축소)
numpy.squeeze(배열, axis=None), 배열객체.squeeze(axis=None)
- 배열에서 지정한 축(axis)을 제거하여 차원(rank)를 줄인다.
- 제거하려는 축의 size는 1이어야 한다.
- 축을 지정하지 않으면 size가 1인 모든 축을 제거한다.
- (3,1,1,2) => (3,2)
a = np.arange(12).reshape(1, 2, 1, 2, 3, 1)
a.shape
(1, 2, 1, 2, 3, 1)
r1 = a.reshape(2, 2, 3)
r1.shape
(2, 2, 3)
r2 = a.squeeze() # reshape 한 새로운 배열을 생헝해서 반환.
r2.shape
(2, 2, 3)
r3 = a.squeeze(axis = 2) # (1, 2, 1, 2, 3, 1)에서 a[2]의 축을 제거.
r3.shape
(1, 2, 2, 3, 1)
r4 = a.squeeze(axis = [0,2]) # 한번에 하나씩 만 제거할 수 있다. (Error)
r4.shape
배열객체.flatten()
- 다차원 배열을 1차원으로 만든다.
a.shape
# a.reshape(12,)
a.reshape(-1)
array([ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11])
print(a.shape)
r = a.flatten() # 다차원 배열을 1차원으로 만든다.
print(r.shape)
r
(1, 2, 1, 2, 3, 1)
(12,)
array([ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11])
a = np.arange(15).reshape(3, 5)
a.shape
(3, 5)
# 2차원 배열 => 0축 <-> 1축
# (3, 5) -> (5, 3)
r = a.T
r.shape
(5, 3)
a2 = np.arange(60).reshape(3, 4, 5)
a2.shape
(3, 4, 5)
# (5, 3, 4) # (2, 0, 1) // (0 => 1, 1 => 2 , 2 => 0), (0번 축을 1번 축으로, 1번 축을 2번 축으로, 2번 축을 0번 축으로)
r2 = np.transpose(a2, (2, 0, 1)) # 대상배열, 축을 어떻게 이동할지
r2.shape
(5, 3, 4)
배열 연산
벡터화 - 벡터 연산
- 배열과 scalar 간의 연산은 원소단위로 계산한다.
- 배열간의 연산은 같은 index의 원소끼리 계산 한다.
- Element-wise(원소별) 연산 이라고도 한다.
- 배열간의 연산시 배열의 형태(shape)가 같아야 한다.
- 배열의 형태가 다른 경우 Broadcast 조건을 만족하면 연산이 가능하다.
배열과 스칼라간 연산
\[\begin{align} 10 - \begin{bmatrix} 1 \\ 2 \\ 3 \\ \end{bmatrix} = \begin{bmatrix} 10 - 1 \\ 10 - 2 \\ 10 - 3 \\ \end{bmatrix} = \begin{bmatrix} 9 \\ 8 \\ 7 \\ \end{bmatrix} \end{align}\] \[\begin{align} 10 \times \begin{bmatrix} 1 & 2 \\ 3 & 4 \end{bmatrix} = \begin{bmatrix} 10\times1 & 10\times2 \\ 10\times3 & 10\times4 \\ \end{bmatrix} = \begin{bmatrix} 10 & 20 \\ 30 & 40 \end{bmatrix} \end{align}\]배열 간의 연산
\(\begin{align} \begin{bmatrix} 1 \\ 2 \\ 3 \\ \end{bmatrix} + \begin{bmatrix} 10 \\ 20 \\ 30 \\ \end{bmatrix} = \begin{bmatrix} 1 + 10 \\ 2 + 20 \\ 3 + 30 \\ \end{bmatrix} = \begin{bmatrix} 11 \\ 22 \\ 33 \\ \end{bmatrix} \end{align}\)
\[\begin{align} \begin{bmatrix} 1 & 2 \\ 3 & 4 \end{bmatrix} + \begin{bmatrix} 10 & 20 \\ 30 & 40 \\ \end{bmatrix} = \begin{bmatrix} 1+10 & 2+20 \\ 3+30 & 4+40 \end{bmatrix} = \begin{bmatrix} 11 & 22 \\ 33 & 44 \end{bmatrix} \end{align}\]
내적 (Dot product) 연산
@
연산자 또는numpy.dot(벡터/행렬, 벡터/행렬)
함수 사용
1차원 배열(벡터)간의 내적
- 같은 index의 원소끼리 곱한뒤 결과를 모두 더한다.
- 벡터간의 내적의 결과는 스칼라가 된다.
- $ x \cdot y $ 또는 $x^T y$로 표현
- 조건
- 두 벡터의 차원(원소의개수)가 같아야 한다.
- 앞의 벡터는 행벡터 뒤의 벡터는 열벡터 이어야 한다.
- numpy 에서는 vector 끼리 연산시 앞의 벡터는 행벡터로 뒤의 벡터는 열벡터로 인식해 처리한다.
행렬간의 내적 (행렬 곱)
- 앞 행렬의 행과 뒤 행렬의 열간에 내적을 한다.
- 행렬과 행렬을 내적하면 그 결과는 행렬이 된다.
- 앞 행렬의 열수와 뒤 행렬의 행수가 같아야 한다.
- 내적의 결과의 형태(shape)는 앞행렬의 행수와 뒤 행렬의 열의 형태를 가진다.
- (3 x 2)와 (2 x 5) = (3 x 5)
- (1 x 5)와 (5 x 1) = (1 x 1)
1. 안쪽이 같으면 계산이 가능하고, 결과는 바깥쪽 행열이다.
x = np.array([1, 2, 3])
y = np.array([4, 5, 6])
r1 = x * y
result = np.sum(r1)
result
32
x @ y, np.dot(x, y)
(32, 32)
A = np.arange(1, 7).reshape(2, 3)
B = np.arange(1, 7).reshape(3, 2)
A.shape, B.shape
((2, 3), (3, 2))
A @ B
array([[22, 28],
[49, 64]])
B @ A
array([[ 9, 12, 15],
[19, 26, 33],
[29, 40, 51]])
내적의 예
가중합
가격: 사과 2000, 귤 1000, 수박 10000
개수: 사과 10, 귤 20, 수박 2
총가격?
2000*10 + 1000 * 20 + 10000 * 2
f = np.array([2000, 1000, 10000])
cnt = np.array([10, 20, 2])
f @ cnt, np.dot(f, cnt)
(60000, 60000)
cnt2 = np.array([[10, 20, 2],
[5, 15, 10],
[10, 10, 10],
[5, 6, 7],
[10, 1, 1]])
cnt2.shape
(5, 3)
2. f 의 행과 열을 바꿔준다.
f2 = f[..., np.newaxis]
f2.shape
f2
array([[ 2000],
[ 1000],
[10000]])
cnt2 @ f2
array([[ 60000],
[125000],
[130000],
[ 86000],
[ 31000]])
np.dot(cnt2, f2)
array([[ 60000],
[125000],
[130000],
[ 86000],
[ 31000]])
기술통계함수
- 통계 결과를 계산해 주는 함수들
- 구문
np.전용함수(배열)
- np.sum(x)
- 일부는
배열.전용함수()
구문 지원- x.sum() - 공통 매개변수
- axis=None: 다차원 배열일 때 통계값을 계산할 axis(축)을 지정한다. None(기본값)은 flatten후 계산한다.
- 배열의 원소 중 누락된 값(NaN - Not a Number) 있을 경우 연산의 결과는 NaN으로 나온다.
- 안전모드 함수
- 배열내 누락된 값(NaN)을 무시하고 계산
- https://docs.scipy.org/doc/numpy-1.15.1/reference/routines.statistics.html
np.random.seed(0)
a = np.random.choice(100, size = 10) # 0 ~ 99 정수
a = a.astype('float32')
a
array([44., 47., 64., 67., 67., 9., 83., 21., 36., 87.], dtype=float32)
np.sum(a), a.sum()
(525.0, 525.0)
a.max(), a.argmax(), a.min(), a.argmin()
(87.0, 9, 9.0, 5)
a.mean(), np.mean(a)
(52.5, 52.5)
np.mean([80, 90, 100])
90.0
np.average([80, 90, 100], weights = [2, 2, 1])
88.0
1. 결측치 대입
a[1] = np.nan
a
array([44., nan, 64., 67., 67., 9., 83., 21., 36., 87.], dtype=float32)
2. 결측치의 개수 확인.
np.sum(np.isnan(a))
1
a.sum(), a.max(), a.mean()
(nan, nan, nan)
3. a.nansum( ) 은 불가능
np.nansum(a), np.nanmax(a), np.nanmean(a)
(478.0, 87.0, 53.11111)
b = np.arange(1, 13).reshape(3, 4)
print(b.shape)
b
(3, 4)
array([[ 1, 2, 3, 4],
[ 5, 6, 7, 8],
[ 9, 10, 11, 12]])
4. axis를 지정하지 않으면 전체 기준 통계량을 계산한다.
b.sum(), b.mean(), b.max()
(78, 6.5, 12)
5. axis = 0 : axis 1은 같고, axis 2의 index는 다른 값끼리 계산.
b.sum(axis = 0)
array([15, 18, 21, 24])
b.sum(axis = 1)
array([10, 26, 42])
c = np.arange(1, 13).reshape(2, 2, 3)
c
array([[[ 1, 2, 3],
[ 4, 5, 6]],
[[ 7, 8, 9],
[10, 11, 12]]])
c.sum(axis = 0)
array([[ 8, 10, 12],
[14, 16, 18]])
6. 지정한 axix의 index는 다르고 나머지 axis의 index는 같은 값들끼리 계산.
c.sum(axis = 1)
array([[ 5, 7, 9],
[17, 19, 21]])
브로드캐스팅
- 사전적의미 : 퍼트린다. 전파한다.
- 형태(shape)가 다른 배열 연산시 배열의 형태를 맞춰 연산이 가능하도록 한다.
- 모든 형태를 다 맞추는 것은 아니고 조건이 맞아야 한다.
- 조건
- 두 배열의 축의 개수가 다르면 작은 축의개수를 가진 배열의 형태(shape)의 앞쪽을 1로 채운다.
- (2, 3) + (3, ) => (2, 3) + (1, 3)
- 두 배열의 차원 수가 같지만 각 차원의 크기가 다른 경우 어느 한 쪽에 1이 있으면 그 1이 다른 배열의 크기와 일치하도록 늘어난다.
- 1 이외의 나머지 축의 크기는 같아야 한다.
- 늘리면서 원소는 복사한다.
- (2, 3) + (1, 3) => (2, 3)+(2, 3)
- 두 배열의 축의 개수가 다르면 작은 축의개수를 가진 배열의 형태(shape)의 앞쪽을 1로 채운다.
x = np.array([1, 2, 3])
y = np.array([2])
x.shape, y.shape
((3,), (1,))
x + y
array([3, 4, 5])
1개 이상인 사이즈는 사이즈가 다르면 계산 안됨.
사이즈가 다른데 둘중 하나가 1이 있으면 계산 가능.
댓글남기기