데이터 과학 numpy 강의

데이터 과학을 위한 파이썬 라이브러리

파이썬 라이브러리

  1. NumPy
  2. SciPy
  3. Pandas
  4. SciKit-learn

시각화 라이브러리

  1. matplotlib
  2. Seaborn

라이브러리 설명

1. NumPy (Numerical Python)

  • 다차원 배열을 다루는 데 사용되는 핵심 라이브러리입니다. 고급 수학 연산과 통계적 연산을 쉽게 할 수 있게 해주며, 다른 데이터 과학 라이브러리의 기반이 됩니다.

2. SciPy (Scientific Python)

  • NumPy를 기반으로 하며, 선형 대수, 수치적 적분, 최적화, 통계 등과 같은 과학적 및 기술적 컴퓨팅에 필요한 더 많은 함수를 제공합니다.

3. Pandas

  • 테이블 형태의 데이터를 효율적으로 처리하고, 데이터프레임(dataframe)이라는 구조를 제공하여 복잡한 데이터 분석과 조작을 단순화합니다. 시계열 분석에도 자주 사용됩니다.

4. SciKit-Learn (Sklearn)

  • 간단하고 효과적인 데이터 마이닝 및 데이터 분석 도구를 제공합니다. 분류, 회귀, 클러스터링 등 다양한 머신 러닝 알고리즘을 포함하고 있습니다.

5. Matplotlib

  • Python에서 2D 그래프와 플롯을 생성할 수 있는 라이브러리입니다. 고품질의 그래픽과 플롯을 다양한 포맷으로 쉽게 생성할 수 있습니다.

6. Seaborn

  • Matplotlib을 기반으로 한 시각화 라이브러리로, 좀 더 현대적이고 세련된 시각화 스타일과 색상을 제공합니다. 복잡한 데이터의 패턴을 이해하기 쉬운 시각화로 표현할 수 있게 도와줍니다.

NumPy 기초

기초

  • 다차원 배열(ndarray): 같은 유형의 요소를 포함하는 배열로, NumPy의 핵심 기능입니다. 배열의 차원은 축(axis)으로 표현됩니다.
  • 배열 속성:
    • ndarray.ndim: 배열의 차원 수를 나타냅니다.
    • ndarray.shape: 배열의 형태를 나타내는 튜플입니다.
    • ndarray.size: 배열 내의 전체 요소 수입니다.
    • ndarray.dtype: 배열 요소의 데이터 유형입니다.
    • ndarray.itemsize: 각 요소의 바이트 크기입니다.

Creating an Array

  • 리스트나 튜플에서 배열 생성: np.array 함수를 사용하여 Python의 리스트나 튜플로부터 NumPy 배열을 생성할 수 있습니다.
  • 배열 생성 함수: np.zeros, np.ones, np.empty 등의 함수를 사용하여 특정 조건을 만족하는 배열을 생성합니다.
  • 데이터 유형 지정: 생성 시 dtype 매개변수를 통해 배열의 데이터 유형을 지정할 수 있습니다.

Creating a Sequence

  • arange 함수: np.arange(start, stop, step) 함수는 시작 값(start)부터 종료 값(stop)까지 step의 간격으로 숫자를 포함하는 배열을 생성합니다. step 매개변수는 선택 사항이며, 지정하지 않으면 기본값은 1입니다. 예를 들어, np.arange(0, 10, 2)는 0부터 시작하여 2씩 증가하는 숫자(0, 2, 4, 6, 8)를 포함하는 배열을 생성합니다.
  • linspace 함수: 시작 값과 종료 값 사이에서 균등하게 분포된 숫자를 포함하는 배열을 생성합니다. 예: np.linspace(0, 1, 5)는 0부터 1까지 균등하게 5개의 숫자를 포함합니다.

배열 인덱싱 및 슬라이싱

  • 배열에서 특정 요소에 접근하거나 배열의 일부를 추출하는 데 사용됩니다.

배열 연산

  • 기본 산술 연산자는 요소별로 작동하며, 복잡한 수학적, 통계적 연산을 위한 다양한 함수가 제공됩니다.

배열 형태 변경

  • reshaperavel 메서드를 통해 배열의 형태를 변경할 수 있으며, 이는 데이터 분석 과정에서 매우 유용합니다.

출력

1차원 배열

  • 1차원 배열은 간단히 행(row)으로 출력됩니다. 예를 들어, np.array([1, 2, 3])[1 2 3]으로 출력됩니다.

2차원 배열

  • 2차원 배열은 행렬 형태로 출력됩니다. 각 내부 배열(또는 리스트)이 행을 구성하며, 출력시 줄바꿈을 통해 차원을 나타냅니다. 예를 들어, np.array([[1, 2, 3], [4, 5, 6]])은 다음과 같이 출력됩니다.
  • [[1 2 3] [4 5 6]]

3차원 이상의 배열

  • 3차원 이상의 배열은 리스트의 리스트의 리스트로 출력됩니다. 여기서, 각 내부 리스트는 더 낮은 차원의 배열을 나타내며, 배열의 깊이에 따라 중첩됩니다. 예를 들어, 3차원 배열은 여러 개의 행렬 리스트로 출력됩니다.

대규모 배열

  • 매우 큰 배열을 출력할 때, NumPy는 배열의 중앙 부분을 생략하고 모서리만 표시하여 전체 배열의 개요를 제공합니다. 이는 출력을 간결하게 유지하면서도 배열의 구조를 파악할 수 있게 해줍니다. 예를 들어, np.arange(10000)은 시작과 끝의 일부 숫자만을 포함하여 출력됩니다.

출력 행동 제어

  • NumPy는 배열 출력 시 자동으로 생략하는 기능을 제공하지만, np.set_printoptions 함수를 사용하여 이러한 행동을 조정할 수 있습니다. 이를 통해 배열을 출력할 때 요소의 생략 여부나 출력할 최대 요소 수 등을 사용자가 직접 설정할 수 있습니다.

연산

요소별 연산

  • 산술 연산: +, -, *, /와 같은 기본 산술 연산자는 배열의 요소별로 작동합니다. 예를 들어, 두 배열을 더하면 각 위치의 요소끼리 더한 결과가 새 배열로 반환됩니다.
  • 배열과 스칼라 간 연산: 배열에 스칼라 값을 더하거나 곱하는 등의 연산도 요소별로 수행됩니다.
  • 비교 연산: 두 배열 간의 비교(==, !=, >, <)도 요소별로 이루어집니다, 결과는 Boolean 배열로 반환됩니다.

복잡한 연산

  • 행렬 곱셈: @ 연산자나 np.dot 함수를 사용하여 두 배열의 행렬 곱셈을 수행할 수 있습니다.
  • 증가/감소 연산: +=, *=과 같은 연산자를 사용하여 배열의 요소를 직접 수정할 수 있습니다.

집계 함수

  • 집계 연산: sum, min, max, cumsum과 같은 함수를 사용하여 배열 전체 또는 특정 축을 따라 연산을 집계할 수 있습니다.
  • 통계 함수: mean, std를 포함하여 배열의 통계적 분석을 위한 함수들도 제공됩니다.

범용 함수 (ufunc)

  • NumPy는 sin, cos, exp, sqrt와 같은 수학적 함수를 범용 함수(ufunc)로 제공합니다. 이러한 함수들은 배열의 각 요소에 대해 계산되며, 배열을 반환합니다.

축을 따른 연산

  • 많은 연산은 axis 매개변수를 지정함으로써 특정 축을 따라 수행될 수 있습니다. 예를 들어, np.sum(arr, axis=0)은 배열의 각 열의 합을 계산합니다.

인덱싱(Indexing)

  • 단일 요소 접근: 배열의 특정 위치에 있는 단일 요소에 접근할 수 있습니다. 예를 들어, arr[2, 1]은 2차원 배열에서 세 번째 행의 두 번째 요소를 반환합니다.
  • 부울 인덱싱: 조건을 만족하는 요소만 선택할 수 있습니다. 예: arr[arr > 5]는 배열 arr에서 5보다 큰 모든 요소를 선택합니다.

슬라이싱(Slicing)

  • 배열의 일부 선택: 배열의 연속적인 요소를 선택하는 데 사용됩니다. 슬라이스는 시작:끝:간격 형태로 지정됩니다. 예를 들어, arr[1:4]은 두 번째 요소부터 네 번째 요소까지의 부분 배열을 생성합니다.
  • 다차원 슬라이싱: 각 차원에 대해 슬라이스를 지정할 수 있습니다. 예: arr[1:5, :3]는 두 번째 요소부터 다섯 번째 요소까지, 그리고 첫 번째 열부터 세 번째 열까지의 2차원 부분 배열을 생성합니다.

반복(Iterating)

  • 1차원 배열: 1차원 배열은 리스트와 유사하게 반복할 수 있습니다. 예: for element in arr:arr의 각 요소에 대해 반복합니다.
  • 다차원 배열: 다차원 배열의 경우, 기본적으로 첫 번째 축(행)을 따라 반복합니다. 예: for row in arr:arr의 각 행에 대해 반복합니다.
  • 모든 요소에 대한 반복: np.nditer() 함수를 사용하면 배열의 모든 요소에 대해 반복적으로 접근할 수 있습니다, 이는 다차원 배열을 효과적으로 반복 처리하는 데 유용합니다.

다차원 배열 다루기

import numpy as np

def f(x,y):
    return 10 * x + y

b = np.fromfunction(f, (5, 4), dtype=int)
print(b)

# Output:
# array([[ 0,  1,  2,  3],
#        [10, 11, 12, 13],
#        [20, 21, 22, 23],
#        [30, 31, 32, 33],
#        [40, 41, 42, 43]])

print(b[2, 3])
# Output: 23

print(b[0:5, 1])  # each row in the second column of b
# Output: array([ 1, 11, 21, 31, 41])

print(b[:, 1])  # equivalent to the previous example
# Output: array([ 1, 11, 21, 31, 41])

print(b[1:3, :])  # each column in the second and third row of b
# Output:
# array([[10, 11, 12, 13],
#        [20, 21, 22, 23]])

b[-1]는 b[-1, :]와 동일합니다. 또한 x[1,2,…]은 x[1,2,:,:,:]와 동일합니다.

NumPy 배열의 flat 속성은 배열을 1차원 반복 가능 객체로 반환합니다. 이를 사용하면 다차원 배열의 모든 요소를 1차원적인 관점에서 접근하고 반복할 수 있습니다.

배열 모양 바꾸기

ravel

  • ravel 함수는 다차원 배열을 1차원 배열로 평탄화합니다. 기본적으로 이 함수는 원본 데이터의 뷰를 반환하므로, 반환된 배열을 수정하면 원본 배열도 영향을 받습니다.

reshape

  • reshape 함수는 주어진 차원으로 배열의 형태를 변경합니다. 이 함수는 또한 원본 데이터의 뷰를 반환하지만, 원본 배열과 다른 형태를 갖게 됩니다. 배열의 총 크기는 변경 전후로 동일해야 합니다.

transpose

  • transpose 함수는 배열의 축을 서로 바꾸어 줍니다. 이는 특히 2차원 배열에 대해 전치(transpose)를 수행할 때 유용합니다. 2차원 배열에 대해서는 간단히 .T 속성을 사용할 수도 있습니다.

resize

  • 열의 크기를 변경하고, 필요한 경우 배열의 내용을 재배치하거나 반복하여 새 크기에 맞춥니다. 원본 배열이 직접 변경되며, 크기를 늘리면 추가된 요소는 0으로 채워지고, 줄이면 데이터가 잘립니다.
  • 차원을 -1로 설정하는 경우, 해당 차원의 크기가 자동으로 계산됩니다. 이는 배열을 재구성할 때 하나의 차원을 “알아서 결정해달라”고 요청하는 것과 같으며, 배열의 총 크기와 다른 차원의 크기를 기반으로 계산됩니다.

원본 변형 여부

  • ravel: 원본 배열의 뷰를 반환하므로, 반환된 배열을 수정하면 원본 배열도 변형됩니다.
  • reshape: 대부분의 경우 원본 배열의 뷰를 반환하지만, 필요한 경우 복사본을 반환할 수 있으며, 이 경우 원본은 변형되지 않습니다.
  • transpose: 항상 원본 배열의 뷰를 반환하므로, 이를 수정하면 원본 배열도 변형됩니다.

ravel과 flatten 비교

  • ravel:
    • 원본 배열의 뷰(view)를 반환합니다.
    • 반환된 배열에 대한 변경사항이 원본 배열에 영향을 줄 수 있습니다.
    • 메모리를 절약하기 위해 가능한 원본 데이터를 복사하지 않습니다.
  • flatten:
    • 원본 배열의 복사본을 반환합니다.
    • 반환된 배열을 수정해도 원본 배열에는 영향을 주지 않습니다.
    • 원본 데이터의 복사본을 만들기 때문에 추가 메모리가 필요합니다.
  • 간단히 말해서, ravel은 원본 배열을 변경할 가능성이 있는 작업에 적합하고, flatten은 원본 배열을 그대로 유지해야 할 때 사용합니다.

Stacking Array

  • np.vstack (Vertical Stack): 배열을 세로로(행 방향으로) 쌓습니다. 예를 들어, 두 개의 2차원 배열을 세로로 결합하면, 결과적으로 행의 수가 늘어납니다.
  • np.hstack (Horizontal Stack): 배열을 가로로(열 방향으로) 쌓습니다. 이 방식으로 결합하면, 열의 수가 증가합니다.
  • np.concatenate: axis 매개변수를 통해 주어진 축을 따라 배열을 결합합니다. axis=0vstack과 유사하게 작동하고, axis=1hstack과 유사하게 작동합니다.
  • column_stack: 이 함수는 1차원 배열을 열 벡터로 간주하고 이들을 가로로(열 방향으로) 쌓아 2차원 배열을 만듭니다. 다차원 배열에 대해서도 사용할 수 있으며, 이 경우에는 마지막 축을 따라 배열을 결합합니다. 간단히 말해, 여러 배열을 옆으로 붙여서 새로운 배열의 열을 형성합니다.
  • row_stack: 이 함수는 주어진 배열을 세로로(행 방향으로) 쌓아 새로운 배열을 만듭니다. np.vstack과 기능적으로 동일하며, 주로 2차원 배열을 생성할 때 사용됩니다. 즉, 여러 배열을 위아래로 붙여서 새로운 배열의 행을 형성합니다.

newaxis

np.newaxis는 NumPy 배열의 차원을 증가시키기 위해 사용됩니다. 이를 사용하여 기존 배열에 새로운 축을 추가할 수 있으며, 이는 배열의 형태를 변경하는 데 유용합니다. np.newaxis는 주로 배열의 차원을 확장하거나, 1차원 배열을 열 벡터나 행 벡터로 변환하는 데 사용됩니다.

Splitting Array

np.hsplit

  • 수평 분할: np.hsplit은 배열을 수평으로, 즉 열 방향으로 분할합니다. 이는 2차원 배열에서 특정 열을 기준으로 배열을 나누고 싶을 때 유용합니다.

np.vsplit

  • 수직 분할: np.vsplit은 배열을 수직으로, 즉 행 방향으로 분할합니다. 이는 2차원 배열에서 특정 행을 기준으로 배열을 나누고 싶을 때 사용됩니다.

Object References

  • 단순한 할당은 복사본을 만들지 않는다.
  • 함수 호출도 복사본을 만들지 않는다.

View

  • 원본 배열과 데이터를 공유하는 배열의 뷰를 의미합니다. 뷰(view)는 기본 데이터의 새로운 인터페이스를 제공하지만, 데이터 자체는 복사하지 않습니다. 이는 메모리를 효율적으로 사용하면서 배열의 일부를 조작할 수 있게 해줍니다.

뷰의 특징:

  • 데이터 공유: 뷰는 원본 배열의 데이터와 메모리를 공유합니다. 따라서 뷰를 통해 데이터를 변경하면 원본 배열에도 영향을 미칩니다.
  • 성능: 데이터를 복사하지 않기 때문에, 뷰를 생성하고 사용하는 것은 매우 빠르고 메모리 효율적입니다.
  • 유연성: 뷰를 사용하면 원본 데이터에 대한 다양한 인터페이스를 생성할 수 있어, 데이터 조작과 분석을 유연하게 할 수 있습니다.

Deep copy

  • arr_copy = arr.copy() # 깊은 복사를 수행합니다.
  • 배열과 그 데이터의 완전한 복사본을 생성하는 과정을 의미합니다. 깊은 복사(deep copy)를 수행하면, 원본 배열과 데이터를 공유하지 않는 새로운 배열이 만들어집니다. 이는 원본 배열을 수정해도 복사된 배열에 영향을 주지 않고, 반대로 복사된 배열을 수정해도 원본 배열이 변경되지 않습니다.

Deep Copy의 특징:

  • 독립성: 깊은 복사를 통해 생성된 배열은 원본 배열로부터 완전히 독립적입니다. 데이터가 별도의 메모리 공간에 저장됩니다.
  • 메모리 사용: 데이터의 완전한 복사본을 만들기 때문에 추가적인 메모리가 필요합니다.
  • 사용 방법: NumPy에서 깊은 복사는 copy 메소드를 사용하여 수행할 수 있습니다.

Leave a Comment