새로운 한 주가 시작되었다. 주말 동안 NumPy-100이라는 레퍼지토리에 있는 문제를 풀어보았는데, 아직 수업에서 배우지 않은 내용이 더 많아서 풀 수 있는 문제는 많지 않았다. 수업 시간에는 NumPy의 기본기 정도만 다루기 때문에 다른 기능들이나 심화 과정은 따로 공부를 더 해보는 것이 좋겠다고 생각했다.
오늘은 NumPy 배열의 연산과 여러 통계 함수, 논리 연산, 조건 연산에 대해 공부했다.
a1 = np.array([1,2,3])
a2 = np.array([4,5,6])
print(a1 + a2)
print(a1 - a2)
# [5 7 9]
# [-3 -3 -3]
a1 = np.arange(1,5).reshape(2,2)
a2 = np.arange(11,15).reshape(2,2)
print(a1)
print(a2)
# [[1 2]
# [3 4]]
# [[11 12]
# [13 14]]
print(a1 + a2)
# [[12 14]
# [16 18]]
print(a2 - a1)
# [[10 10]
# [10 10]]
a1 = np.array([1,2,3,4])
print(a1 + 10)
# [11 12 13 14]
print(a1 * 2)
# [2 4 6 8]
a1 = np.arange(1,5).reshape(2,2)
a2 = np.arange(11,15).reshape(2,2)
print(a1)
print(a2)
# [[1 2]
# [3 4]]
# [[11 12]
# [13 14]]
print(a1 + 5)
# [[6 7]
# [8 9]]
print(a2 * 3)
# [[33 36]
# [39 42]]
print(a2 / 2)
# [[5.5 6. ]
# [6.5 7. ]]
배열의 구조가 다른 경우 에러 발생
a1 = np.array([1,2,3])
a2 = np.array([1,2])
print(a1 + a2)
# ValueError: operands could not be broadcast together with shapes (3,) (2,)
a1 = np.array([[1,2,3],[4,5,6]]) # (2, 3)
a2 = np.array([10,20,30]) # (3, )
# 1차원 (3, )
[10,20,30]
# 2차원으로 변혈 (1,3)
[[10,20,30]]
# 2차원의 행이 2로 확장
[[10,20,30], [10,20,30]]
print(a1 + a2)
# [[11 22 33]
# [14 25 36]]
a1 = np.array([[1], [2], [3]]) # (3, 1)
a2 = np.array([10,20,30]) # (3, )
# a2 : (3, ) -> (1, 3)으로 변형
[[10, 20, 30]]
# a1과 a2비교 : a1 = (3, 1), a2 = (1, 3)
# 2차원의 경우 : 3 vs 1 -> a2의 2차원이 3으로 확장
[[10, 20, 30], [10, 20, 30], [10, 20, 30]]
# 1차원의 경우 : 1 vs 3 -> a1의 1차원이 3으로 확장
[[1, 1, 1], [2, 2, 2], [3, 3, 3]]
print(a1 + a2)
브로드캐스팅이 불가능한 경우
a1 = np.ones((2,3))
a2 = np.ones((3,2))
print(a1 + a2)
# ValueError: operands could not be broadcast together with shapes (2,3) (3,2)
sum( ) : 원소의 합mean( ) : 원소의 평균std( ) : 표준편차max( ) : 최대값min( ) : 최소값argmax( ) : 최대값의 인덱스argmin( ) : 최소값의 인덱스a = np.array([[1,2,3],[4,5,6]])
print("원소의 합 :", np.sum(a))
print("원소의 평균 :", np.mean(a))
print("표준편차 :", np.std(a))
print("최대값 :", np.max(a))
print("최소값 :", np.min(a))
print("최대값의 인덱스 :", np.argmax(a))
print("최소값의 인덱스 :", np.argmin(a))
# 원소의 합 : 21
# 원소의 평균 : 3.5
# 표준편차 : 1.707825127659933
# 최대값 : 6
# 최소값 : 1
# 최대값의 인덱스 : 5
# 최대값의 인덱스 : 0 a = np.array([[1,2,3],
[4,5,6]])
print("행기준", np.sum(a, axis=0))
print("열기준", np.sum(a, axis=1))
# 행기준 [5 7 9]
# 열기준 [ 6 15]
print("행기준 평균", np.mean(a, axis=0))
print("열기준 평균", np.mean(a, axis=1))
# 행기준 평균 [2.5 3.5 4.5]
# 열기준 평균 [2. 5.]
cumsum( ) : 누적 합cumprod( ) : 누적 곱arr = np.array([1,2,3,4])
print(np.cumsum(arr)) # 누적 합
# [ 1 3 6 10]
print(np.cumprod(arr)) # 누적 곱
# [ 1 2 6 24]
np.where( ) : 조건 기반 선택 함수arr = np.array([10,20,30,40,50])
result = np.where(arr > 30, "high", "low")
print(result)
# ['low' 'low' 'low' 'high' 'high']
arr = np.array([10,20,30,40,50])
result = np.where(arr > 30)
print(result)
# (array([3, 4]),)
print(arr[result]) # 원본 배열에 Fancy indexing
# [40 50]
np.where( ) 함수를 중첩으로 사용 가능arr = np.array([[5,50,95], [20,75,10], [60,30,85]])
result = np.where(arr >= 70, "A", np.where(arr >= 30, "B", "C"))
print(result)
# [['C' 'B' 'A']
# ['C' 'A' 'C']
# ['B' 'B' 'A']]
arr = np.array([10,20,30,40,50])
mask = (arr > 10) & (arr < 50)
print(arr[mask])
# [20 30 40]
mask_or = (arr < 20) | (arr > 40)
print(arr[mask_or])
# [10 50]
mask_not = ~(arr > 30)
print(arr[mask_not])
# [10 20 30]
연산 파트는 지금까지 배운 내용들과 비슷해서 무난하게 따라갈 수 있었다. 하지만 axis를 사용하는 축 단위 연산에서 좀 막혔다. axis=0과 1의 개념은 이해했다고 생각했는데, 막상 문제를 풀 때는 계속 헷갈렸다. 어떤 연산을 써야 할지 충분히 생각하고 답을 작성했는데, 확인해보니 모든 문제를 반대로 작성했었다. 처음엔 당황스러웠지만 문제를 다시 천천히 읽어보면서 내가 어디서 헷갈렸는지 파악할 수 있었다. 이제 axis 문제에 어떤 식으로 접근해야 할지 감을 잡은 것 같아서 다음번엔 실수하지 않을 것 같다.