STUDY/ML DL

numpy : 배열 인덱싱과 슬라이싱, boolean 인덱싱

sed 2026. 5. 8. 21:19
SMALL

배열 인덱싱과 슬라이싱

numpy 배열도 파이썬 리스트처럼 인덱싱과 슬라이싱이 가능하다.

다만 2차원 배열에서는 행과 열을 기준으로 위치를 생각해야 한다.

 

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

 

위 배열은 다음과 같은 구조를 가진다.

[[1 2 3]   # 0번째 행
 [4 5 6]   # 1번째 행
 [7 8 9]]  # 2번째 행
 

행과 열의 인덱스를 함께 보면 다음과 같다.

        0열  1열  2열
0행     1    2    3
1행     4    5    6
2행     7    8    9
 

따라서 numpy 배열에서는 보통 다음과 같은 형태로 원하는 값을 가져올 수 있다.

a[행, 열]
 

 

 

a[0]은 0번째 행, 즉 첫 번째 행 전체를 가져온다.

print(a[0])
[1 2 3]
 

 

 

-1은 파이썬에서 마지막 위치를 의미한다.
따라서 a[-1]은 마지막 행을 가져온다.
print(a[-1])
[7 8 9]
 

 

 

a[1:]1번째 행부터 끝까지 가져온다는 뜻이다.
즉, 첫 번째 행은 제외하고 두 번째 행부터 마지막 행까지 가져온다.

print(a[1:])
[[4 5 6]
 [7 8 9]]
 

 

 
 
:은 전체 범위를 의미한다.

따라서 a[:]는 배열 전체를 그대로 가져온다.

print(a[:])
[[1 2 3]
 [4 5 6]
 [7 8 9]]
 

 

 
 
아래 두 코드는 모두 같은 값을 가져온다.

a[0][2]는 먼저 a[0]으로 첫 번째 행을 가져온 뒤, 그 행에서 인덱스 2번 값을 가져오는 방식이다.

print(a[0][2])
print(a[0, 2])
a[0] -> [1 2 3]
a[0][2] -> 3
 

 

반면 a[0, 2]는 처음부터 0번째 행, 2번째 열의 값을 바로 가져온다.

a[0, 2] -> 3
 

따라서 두 코드의 출력 결과는 모두 다음과 같다.

3
3
 

numpy에서는 보통 a[0, 2]처럼 쉼표를 사용하는 방식을 더 많이 쓴다.
행과 열을 한 번에 지정할 수 있어서 더 직관적이기 때문이다.

 
 
 

a[1, :]는 1번째 행의 모든 열을 가져온다는 뜻이다.

여기서 1은 행을 의미하고, :은 모든 열을 의미한다.

print(a[1, :])
[4 5 6]
 

즉, 두 번째 행 전체를 가져온다.

 

 
 

a[1, 0:3:2]는 1번째 행에서 일부 열만 가져오는 코드이다.

슬라이싱 구조는 다음과 같다.

print(a[1, 0:3:2])
시작:끝:간격
 

따라서 0:3:2는 0번 인덱스부터 3번 인덱스 전까지, 2칸씩 건너뛰며 가져오라는 뜻이다.

 

 

1번째 행은 다음과 같다.

[4 5 6]
 

여기서 인덱스를 보면 다음과 같다.

인덱스:  0  1  2
값:      4  5  6
 

0:3:2는 인덱스 0과 2를 가져오므로 결과는 다음과 같다.

[4 6]
 

정리하면 numpy 배열에서 인덱싱은 보통 다음 형태로 이해하면 된다.

a[행, 열]
 

그리고 :은 전체를 의미한다.

a[1, :]   # 1번째 행의 모든 열
a[:, 1]   # 모든 행의 1번째 열
 

즉, 행과 열을 기준으로 원하는 부분만 골라서 가져오는 것이 numpy 인덱싱과 슬라이싱의 핵심이다.

 

 

 

Boolean indexing

이번에는 조건을 이용해서 배열의 특정 값만 가져오는 방법을 살펴보자.
이를 boolean indexing이라고 한다.

 

아래와 같은 코드가 있을 때, 출력 결과는 `False` 이다.

a = [1, 2, 3, 4, 5, 6, 7]
print(a == 3)

 

여기서 a는 numpy 배열이 아니라 파이썬 리스트이다.
따라서 a == 3은 리스트 안의 각 원소가 3인지 비교하는 것이 아니라, 리스트 전체가 숫자 3과 같은지 비교한다.

즉 [1, 2, 3, 4, 5, 6, 7]이라는 리스트 자체는 숫자 3이 아니므로 False가 출력된다.

 

반면 numpy 배열에서는 원소별 비교가 가능하다.

b = np.array([[1, 23, 4, 3],
              [3, 3, 3, 4]])

print(b == 3)

 

위 코드에 대한 출력 결과는 아래와 같다.

[[False False False  True]
 [ True  True  True False]]

 

b == 3은 배열 b의 각 원소가 3인지 아닌지를 비교한다.
값이 3이면 True, 3이 아니면 False가 된다.

 

즉, 내부적으로는 다음처럼 비교되는 것이다.

[[1==3   23==3   4==3   3==3]
 [3==3    3==3   3==3   4==3]]
 

 

그래서 결과는 True와 False로 이루어진 배열이 된다.

print(b[b == 3])
 

출력 결과는 다음과 같다.

[3 3 3 3]
 

 

b[b == 3]은 b에서 조건이 True인 값만 가져온다.
즉, 값이 3인 원소만 골라서 출력한다.

 

정리하면 boolean indexing은 다음과 같은 구조로 이해하면 된다.

배열[조건]
 

조건을 만족하는 값만 배열에서 꺼내오는 방식이다.

 

 

조건으로 행 선택하기

boolean indexing은 특정 값만 가져올 수도 있지만, 조건에 맞는 행 전체를 가져올 때도 사용할 수 있다.

a = np.random.randn(3, 3)
b = np.random.rand(3, 3)

print(a)
print(b)
print(a[a[:, 0] < 0, :])
 

출력 결과는 다음과 같다.

[[-1.05496538 -0.44234037  1.63802107]
 [ 1.92413339 -0.2624839  -1.55682184]
 [-0.84519315  1.44659377  1.21580899]]
[[0.42585743 0.91853316 0.66597456]
 [0.18507251 0.80918659 0.70171109]
 [0.43317655 0.25002021 0.70864695]]
[[-1.05496538 -0.44234037  1.63802107]
 [-0.84519315  1.44659377  1.21580899]]
 

먼저 np.random.randn(3, 3)은 정규분포를 따르는 3행 3열 배열을 만든다.

np.random.rand(3, 3)은 0과 1 사이의 값을 가지는 3행 3열 배열을 만든다.

 

여기서 실제로 조건에 사용된 배열은 a이다.

print(a[a[:, 0] < 0, :])
 

이 코드를 나누어 보면 먼저 a[:, 0]이 실행된다.

 
a[:, 0]
 

:은 모든 행을 의미하고, 0은 0번째 열을 의미한다.
따라서 a[:, 0]은 모든 행에서 첫 번째 열만 가져온다.

 

위 예시에서 a는 다음과 같다.

[[-1.05496538 -0.44234037  1.63802107]
 [ 1.92413339 -0.2624839  -1.55682184]
 [-0.84519315  1.44659377  1.21580899]]
 

 

여기서 첫 번째 열만 가져오면 다음과 같다.

[-1.05496538  1.92413339 -0.84519315]
 

 

이제 이 값들이 0보다 작은지 비교한다.

a[:, 0] < 0
 

 

결과는 다음과 같다.

[ True False  True]
 

즉, 0번째 행과 2번째 행은 첫 번째 열의 값이 0보다 작고, 1번째 행은 0보다 크다는 뜻이다.

 

마지막으로 이 조건을 이용해 행을 선택한다.

a[a[:, 0] < 0, :]
 

 

앞부분의 a[:, 0] < 0은 가져올 행을 고르는 조건이고, 뒤의 :은 선택된 행의 모든 열을 가져오라는 의미이다.

a[조건, 모든 열]
 

 

따라서 첫 번째 열이 0보다 작은 행만 남게 된다.

[[-1.05496538 -0.44234037  1.63802107]
 [-0.84519315  1.44659377  1.21580899]]
 

 

정리하면, boolean indexing은 원하는 조건을 만족하는 값이나 행만 뽑아낼 때 사용한다.

b[b == 3]          # b에서 값이 3인 원소만 가져오기
a[a[:, 0] < 0, :]  # 첫 번째 열이 0보다 작은 행만 가져오기
 

데이터 분석에서는 특정 조건을 만족하는 데이터만 골라낼 때 자주 사용된다.

LIST