[9일차-2] Python, 데이터분석

송정근·2026년 6월 1일

7. NumPy란?

NumPy는 Python에서 수치 계산과 데이터 분석을 효율적으로 수행하기 위해 사용하는 대표적인 라이브러리이다.

NumPy의 핵심은 ndarray라는 다차원 배열 객체이다.

NumPy가 자주 사용되는 이유는 다음과 같다.

  • 일반 Python 리스트보다 대량 연산이 빠르다.
  • 다차원 배열을 쉽게 다룰 수 있다.
  • 반복문 없이 배열 전체에 연산을 적용할 수 있다.
  • 행렬 연산, 통계, 선형대수, 난수 생성 기능을 제공한다.
  • pandas, scikit-learn, TensorFlow 등 많은 데이터 분석 라이브러리의 기반이 된다.

7.1 설치와 import

pip install numpy

또는 다음처럼 설치할 수 있다.

python -m pip install numpy

NumPy는 관례적으로 np라는 별칭으로 import한다.

import numpy as np

8. ndarray

ndarray는 N-dimensional array의 줄임말로, NumPy의 핵심 자료구조이다. 같은 자료형의 데이터를 다차원 형태로 저장하고 빠르게 연산할 수 있다.

8.1 1차원 배열과 2차원 배열

import numpy as np

ndarr1 = np.array([1, 2, 3, 4])
print(ndarr1)
print(type(ndarr1))
print(type(ndarr1[0]))

ndarr2 = np.array([[1, 2, 3], [4, 5, 6]])
print(ndarr2)
print(type(ndarr2))
print(type(ndarr2[0]))

출력 결과:

[1 2 3 4]
<class 'numpy.ndarray'>
<class 'numpy.int64'>
[[1 2 3]
 [4 5 6]]
<class 'numpy.ndarray'>
<class 'numpy.ndarray'>

8.2 리스트와 ndarray 변환

import numpy as np

list1 = [1, 2, 3, 4]
ndarr1 = np.array(list1)
print(ndarr1)
print(type(ndarr1))

list2 = ndarr1.tolist()
print(list2)
print(type(list2))

출력 결과:

[1 2 3 4]
<class 'numpy.ndarray'>
[1, 2, 3, 4]
<class 'list'>

8.3 ndarray의 자료형 통일

Python 리스트는 서로 다른 타입을 함께 담을 수 있다.

list1 = [1, 3.14, "Python", True]

print(list1)
print(type(list1[0]))
print(type(list1[1]))
print(type(list1[2]))
print(type(list1[3]))

출력 결과:

[1, 3.14, 'Python', True]
<class 'int'>
<class 'float'>
<class 'str'>
<class 'bool'>

반면 NumPy 배열은 하나의 dtype으로 통일된다.

import numpy as np

ndarr1 = np.array([1, 2, 3.14, True])

print(ndarr1)
print(ndarr1.dtype)
print(type(ndarr1[0]))

출력 결과:

[1.   2.   3.14 1.  ]
float64
<class 'numpy.float64'>

정수, 실수, 불리언이 섞여 있지만 NumPy는 더 넓은 표현이 가능한 float64로 통일한다.

문자열이 섞이면 전체가 문자열 타입으로 변환될 수 있다.

import numpy as np

ndarr2 = np.array(["1", 2, 3.14, True])

print(ndarr2)
print(ndarr2.dtype)
print(type(ndarr2[0]))

출력 결과:

['1' '2' '3.14' 'True']
<U32
<class 'numpy.str_'>

8.4 dtype 직접 지정하기

import numpy as np

ndarr = np.array([1, 2, 3.14, True], dtype=int)

print(ndarr)
print(ndarr.dtype)

출력 결과:

[1 2 3 1]
int64

dtype=int를 지정하면 가능한 값들이 정수로 변환된다. 3.14는 3, True는 1로 변환된다.

8.5 shape, ndim, dtype

NumPy 배열을 다룰 때는 배열의 구조를 확인하는 속성이 중요하다.

import numpy as np

arr = np.array([[1, 2, 3], [4, 5, 6]])

print("shape:", arr.shape)
print("ndim:", arr.ndim)
print("dtype:", arr.dtype)
print("size:", arr.size)

출력 결과:

shape: (2, 3)
ndim: 2
dtype: int64
size: 6
속성의미
shape배열의 형태
ndim배열의 차원 수
dtype배열 원소의 자료형
size전체 원소 개수

9. 인덱싱과 슬라이싱

NumPy 배열은 리스트처럼 인덱싱과 슬라이싱을 지원한다. 다차원 배열에서는 arr[행, 열] 형태로 접근할 수 있다.

9.1 1차원 배열 인덱싱과 슬라이싱

import numpy as np

fruits = np.array(["딸기", "수박", "바나나", "체리", "복숭아"])

print(fruits)
print(fruits.shape)

print(fruits[0])
print(fruits[4])
print(fruits[-1])
print(fruits[-2])

print(fruits[0:3])
print(fruits[2:])
print(fruits[:3])

출력 결과:

['딸기' '수박' '바나나' '체리' '복숭아']
(5,)
딸기
복숭아
복숭아
체리
['딸기' '수박' '바나나']
['바나나' '체리' '복숭아']
['딸기' '수박' '바나나']

9.2 2차원 배열 인덱싱

import numpy as np

arr = np.array([
    [1, 2, 3, 4],
    [5, 6, 7, 8],
    [9, 10, 11, 12],
])

print(arr)
print(arr.shape)

print(arr[0, :])
print(arr[0])
print(arr[:, 0])
print(arr[1, 2])

출력 결과:

[[ 1  2  3  4]
 [ 5  6  7  8]
 [ 9 10 11 12]]
(3, 4)
[1 2 3 4]
[1 2 3 4]
[1 5 9]
7

9.3 Fancy Indexing

Fancy indexing은 인덱스 목록을 이용해 원하는 위치의 값들을 한 번에 가져오는 방식이다.

import numpy as np

arr = np.array([10, 15, 2, 8, 20, 90, 85, 44, 23, 32])
idx = [2, 5, 9]

print(arr[idx])

arr2d = np.array([
    [1, 2, 3, 4],
    [5, 6, 7, 8],
    [9, 10, 11, 12],
])

print(arr2d[[0, 1], :])

출력 결과:

[ 2 90 32]
[[1 2 3 4]
 [5 6 7 8]]

9.4 Boolean Indexing

Boolean indexing은 조건에 맞는 값만 선택하는 방식이다.

import numpy as np

arr = np.array([
    [1, 2, 3, 4],
    [5, 6, 7, 8],
    [9, 10, 11, 12],
])

print(arr > 7)
print(arr[arr > 7])

출력 결과:

[[False False False False]
 [False False False  True]
 [ True  True  True  True]]
[ 8  9 10 11 12]

Boolean indexing은 조건 필터링에 매우 자주 사용된다.


10. 행렬 연산

NumPy는 다차원 배열을 이용해 행렬 연산을 수행할 수 있다. 행렬 연산은 데이터 과학, 머신러닝, 통계, 컴퓨터 그래픽스 등에서 중요하게 사용된다.

10.1 스칼라, 벡터, 행렬

개념의미예시
스칼라숫자 하나3, 3.14
벡터숫자가 1차원으로 나열된 구조[1, 2, 3]
행렬숫자가 행과 열을 가진 2차원 표 형태로 저장된 구조[[1, 2], [3, 4]]

10.2 원소별 연산

크기가 같은 배열끼리는 같은 위치의 원소끼리 연산된다.

import numpy as np

a = np.array([[1, 2, 3],
              [2, 3, 4]])
b = np.array([[3, 4, 5],
              [1, 2, 3]])

print(a.shape, b.shape)
print(a + b)
print(a - b)
print(a * b)
print(a / b)

출력 결과:

(2, 3) (2, 3)
[[4 6 8]
 [3 5 7]]
[[-2 -2 -2]
 [ 1  1  1]]
[[ 3  8 15]
 [ 2  6 12]]
[[0.33333333 0.5        0.6       ]
 [2.         1.5        1.33333333]]

a * b는 행렬 곱셈이 아니라 같은 위치의 원소끼리 곱하는 연산이다.

10.3 행렬 곱셈

행렬 곱셈은 앞 행렬의 열 개수와 뒤 행렬의 행 개수가 같아야 가능하다.

import numpy as np

a = np.array([
    [1, 2, 3],
    [1, 2, 3],
    [2, 3, 4],
])

b = np.array([
    [1, 2],
    [3, 4],
    [5, 6],
])

print(a.shape)
print(b.shape)

print(a @ b)
print(np.dot(a, b))

출력 결과:

(3, 3)
(3, 2)
[[22 28]
 [22 28]
 [31 40]]
[[22 28]
 [22 28]
 [31 40]]

@와 np.dot()은 위 예제에서 행렬 곱셈을 수행한다.

10.4 벡터 내적

내적은 두 벡터를 곱해 하나의 숫자인 스칼라를 만드는 연산이다.

import numpy as np

a = np.array([1, 2, 3])
b = np.array([4, 5, 6])

print(np.dot(a, b))

출력 결과:

32

계산 과정은 1*4 + 2*5 + 3*6 = 32이다.

10.5 브로드캐스팅

브로드캐스팅(broadcasting)은 모양이 다른 배열끼리도 규칙에 맞으면 자동으로 형태를 맞춰 연산하는 기능이다.

import numpy as np

scores = np.array([70, 80, 90])

print(scores + 10)

출력 결과:

[ 80  90 100]

스칼라 10이 배열의 모든 원소에 더해진다. 반복문 없이 배열 전체에 연산을 적용할 수 있는 것이 NumPy의 큰 장점이다.


11. 정렬

NumPy의 np.sort()는 배열을 정렬한 복사본을 반환한다. 원본 배열은 기본적으로 변경되지 않는다.

11.1 1차원 배열 정렬

import numpy as np

arr = np.array([1, 10, 5, 7, 2, 4, 3, 6, 8, 9])

print(arr)
print(np.sort(arr))
print(arr)
print(np.sort(arr)[::-1])

출력 결과:

[ 1 10  5  7  2  4  3  6  8  9]
[ 1  2  3  4  5  6  7  8  9 10]
[ 1 10  5  7  2  4  3  6  8  9]
[10  9  8  7  6  5  4  3  2  1]

11.2 2차원 배열 정렬

import numpy as np

arr = np.array([
    [11, 10, 12, 9],
    [3, 1, 4, 2],
    [5, 6, 7, 8],
])

print(np.sort(arr, axis=0))
print(np.sort(arr, axis=1))
print(np.sort(arr, axis=1)[:, ::-1])

출력 결과:

[[ 3  1  4  2]
 [ 5  6  7  8]
 [11 10 12  9]]
[[ 9 10 11 12]
 [ 1  2  3  4]
 [ 5  6  7  8]]
[[12 11 10  9]
 [ 4  3  2  1]
 [ 8  7  6  5]]

axis=0은 열 방향, axis=1은 행 방향으로 정렬한다.

11.3 3차원 배열 정렬

import numpy as np

arr = np.array([
    [
        [9, 3, 5],
        [8, 1, 7],
    ],
    [
        [4, 6, 2],
        [10, 0, 11],
    ],
])

print(arr.shape)

result = np.sort(arr, axis=-1)
print(result)

출력 결과:

(2, 2, 3)
[[[ 3  5  9]
  [ 1  7  8]]

 [[ 2  4  6]
  [ 0 10 11]]]

axis=-1은 마지막 축을 기준으로 정렬한다.


12. 자주 쓰는 NumPy 기능

원문 내용에 추가로, NumPy를 사용할 때 자주 만나는 기능 몇 가지를 정리한다.

12.1 배열 생성 함수

import numpy as np

print(np.zeros((2, 3)))
print(np.ones((2, 3)))
print(np.arange(1, 10, 2))
print(np.linspace(0, 1, 5))

출력 결과:

[[0. 0. 0.]
 [0. 0. 0.]]
[[1. 1. 1.]
 [1. 1. 1.]]
[1 3 5 7 9]
[0.   0.25 0.5  0.75 1.  ]
함수설명
np.zeros(shape)0으로 채운 배열 생성
np.ones(shape)1로 채운 배열 생성
np.arange(start, stop, step)범위 기반 배열 생성
np.linspace(start, stop, count)구간을 균등하게 나눈 배열 생성

12.2 reshape

reshape()는 배열의 전체 원소 개수를 유지하면서 모양을 바꾼다.

import numpy as np

arr = np.arange(1, 7)
reshaped = arr.reshape(2, 3)

print(arr)
print(reshaped)

출력 결과:

[1 2 3 4 5 6]
[[1 2 3]
 [4 5 6]]

12.3 통계 함수

import numpy as np

scores = np.array([70, 80, 90, 100])

print("합계:", np.sum(scores))
print("평균:", np.mean(scores))
print("최댓값:", np.max(scores))
print("최솟값:", np.min(scores))

출력 결과:

합계: 340
평균: 85.0
최댓값: 100
최솟값: 70

13. 마무리

이번 글에서는 파이썬의 코드 재사용과 데이터 분석 기초를 함께 정리했다.

주제핵심
모듈.py 파일 단위로 코드 재사용
패키지여러 모듈을 폴더 단위로 묶어 관리
__name__직접 실행과 import 실행 구분
가상환경프로젝트별 패키지 환경 분리
requirements.txt패키지 설치 환경 재현
NumPy빠른 수치 계산을 위한 배열 라이브러리
ndarrayNumPy의 핵심 다차원 배열 객체
인덱싱/슬라이싱배열에서 원하는 위치나 조건의 데이터 선택
행렬 연산벡터, 행렬 기반 계산 수행
정렬축(axis)을 기준으로 배열 정렬

모듈과 패키지는 프로젝트 구조를 정리하는 도구이고, 가상환경과 requirements.txt는 실행 환경을 안정적으로 관리하는 도구이다. NumPy는 대량의 수치 데이터를 빠르게 처리하기 위한 기본 라이브러리이므로 데이터 분석을 공부한다면 반드시 익숙해져야 한다.

출처 및 참고 자료

본 정리는 강의 내용과 아래 자료를 참고하여 학습 목적으로 작성하였습니다.

https://ryuzyproject.tistory.com/294

profile
기록하며 성장하는 개발자

0개의 댓글