STUDY

[Python] Numpy (배열 조회 / 배열 변환)

moru_xz 2023. 2. 12. 18:28

3. 배열 조회

배열 속성 정보

def array_info(array) :
    print(array)
    print('ndim:', array.ndim)
    print('shape:', array.shape)
    print('dtype:', array.dtype)
    print('size:', array.size)
    print('itemsize:', array.itemsize)
    print('nbytes:', array.nbytes)
    print('strides:', array.strides)
array_info(a1)
>>
[4 5 6 4 5]
ndim: 1
shape: (5,)
dtype: int64
size: 5
itemsize: 8
nbytes: 40
strides: (8,)

ndim: 차원

itemsize: element 하나가 8바이트다 

nbytes = itemsize * size

strides는 4 -> 5 넘어가는데 8바이트 필요

array_info(a2)
>>
[[1 2 3]
 [4 5 6]
 [7 8 9]]
ndim: 2
shape: (3, 3)
dtype: int64
size: 9
itemsize: 8
nbytes: 72
strides: (24, 8)
array_info(a3)
>>
[[[1 2 3]
  [4 5 6]
  [7 8 9]]

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

 [[1 2 3]
  [4 5 6]
  [7 8 9]]]
ndim: 3
shape: (3, 3, 3)
dtype: int64
size: 27
itemsize: 8
nbytes: 216
strides: (72, 24, 8)

인덱싱(Indexing)

print(a1)
print(a1[0])
print(a1[-1])
>>
[4 5 6 4 5]
4
5
print(a3)
print(a3[0, 0, 0])
print(a3[1, 1, 1])
print(a3[2, 2, 2])
print(a3[2, -1, -1])
>>
[[[1 2 3]
  [4 5 6]
  [7 8 9]]

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

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

슬라이싱(Slicing)

  • 슬라이싱 구문: a[start:stop:step]
  • 기본값: start = 0, stop = ndim, step = 1
print(a1)
print(a1[0:2])
print(a1[0:])
print(a1[::2])
print(a1[::-1])
>>
[4 5 6 4 5]
[4 5]
[4 5 6 4 5]
[4 6 5]
[5 4 6 5 4]
print(a2)
print(a2[1])
>>
[[1 2 3]
 [4 5 6]
 [7 8 9]]
[4 5 6]
print(a2[1, 0:])
>> [4 5 6]
print(a2[:2,  :2])
>> 
[[1 2]
 [4 5]]
print(a2[::-1, ::-1])
>>
[[9 8 7]
 [6 5 4]
 [3 2 1]]

불리언 인덱싱(Boolean Indexing)

  • 배열 각 요소의 선택 여부를 불리언(True or False)로 지정
  • True 값인 인덱스의 값만 조회
print(a1)
bi = [False, True, True, False, True]
print(a1[bi])
>>
[4 5 6 4 5]
[5 6 5]

-> 4 5 6 4 5 중에서 True인 값만 나온거임 

print(a2)
bi = np.random.randint(0, 2,(3,3), dtype = bool)
print(bi)
print(a2[bi])
>>
[[1 2 3]
 [4 5 6]
 [7 8 9]]
[[False False False]
 [ True False  True]
 [False False  True]]
[4 6 9]

-> (0,2,(3,3), dtype = bool) 이어야 하는데 True or False 니까 0,3 이런거 안됨 

 

팬시 인덱싱(Fancy Indexing)

print(a1)
print([a1[0], a1[2]])
>>
[9 4 3 4 4]
[9, 3]
ind = [0,2]
print(a1[ind])
>>  [9 3]
ind = np.array([[0,1],
               [2, 0]])
print(a1[ind])
>>
[[9 4]
 [3 9]]

-> 1차원에 2차원 인덱싱 넣어주면 2차원으로 나옴

 

print(a2)
row = np.array([0,2])
col = np.array([1,2])
print(a2[row, col])

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

row는 123 / 456 / 789 중에 0이니까 123, 여기서 col은 1이니까 2

row는 123 / 456 / 789 중에 2니까 789, 여기서 col은  2니까 9

 

4. 배열 값 삽입 / 수정 / 삭제 / 복사

배열 값 삽입

  • insert(): 배열의 특정 위치에 값 삽입
  • axis를 지정하지 않으면 1차원 배열로 변환
  • 추가할 방향을 axis로 지정
  • 원본 배열 변경없이 새로운 배열 반환
print(a1)
b1= np.insert(a1, 0, 10)
print(b1)
print(a1) #원본은 바뀌지 않음
>>
[4 5 6 4 5]
[10  4  5  6  4  5]
[4 5 6 4 5]

-> 원본은 바뀌지 않음 / 0 자리에 10 삽입

print(a2)
b2 = np.insert(a2, 1, 10, axis = 0)
print(b2)
>>
[[1 2 3]
 [4 5 6]
 [7 8 9]]
[[ 1  2  3]
 [10 10 10]
 [ 4  5  6]
 [ 7  8  9]]
print(a2)
b2 = np.insert(a2, 1, 10, axis = 1)
print(b2)
>>
[[1 2 3]
 [4 5 6]
 [7 8 9]]
[[ 1 10  2  3]
 [ 4 10  5  6]
 [ 7 10  8  9]]

-> axis 지정

 

배열 값 수정

  • 배열의 인덱싱으로 접근하여 값 수정
print(a1)
a1[0] = 1
a1[1] = 2
a1[2] = 3
print(a1)
>>
[4 5 6 4 5]
[1 2 3 4 5]
a1[:1] = 9
print(a1)
>> [9 2 3 4 5]
i = np.array([1, 3, 4])
a1[i] = 0
print(a1)
>> [9 0 3 0 0]
print(a2)
a2[0,0] = 1
a2[1,1] = 2
a2[2,2] = 3
a2[0] = 1
print(a2)
>>
[[1 2 3]
 [4 5 6]
 [7 8 9]]
[[1 1 1]
 [4 2 6]
 [7 8 3]]

배열 값 삭제

  • delete(): 배열의 특정 위치에 값 삭제
  • axis를 지정하지 않으면 1차원 배열로 변환
  • 삭제할 방향을 axis로 지정
  • 원본 배열 변경 없이 새로운 배열 반환
print(a1)
b1 = np.delete(a1, 1)
print(b1)
print(a1)
>>
[9 0 3 0 0]
[9 3 0 0]
[9 0 3 0 0]
print(a2)
b2 = np.delete(a2, 1, axis = 1)
print(b2)
>>
[[1 1 1]
 [4 2 6]
 [7 8 3]]
[[1 1]
 [4 6]
 [7 3]]

 

 

배열 복사

  • 리스트 자료형과 달리 배열의 슬라이스는 복사본이 아님
print(a2)
print(a2[:2, :2])
a2_sub = a2[:2, :2]
print(a2_sub)

>>
[[1 1 1]
 [4 2 6]
 [7 8 3]]
[[1 1]
 [4 2]]
[[1 1]
 [4 2]]
a2_sub[:,1] = 0
print(a2_sub)
>>
[[1 0]
 [4 0]]
print(a2)
>>
[[1 0 1]
 [4 0 6]
 [7 8 3]]

-> 원본도 바뀜 => 리스트는 바뀌지 않지만 넘파이는 바뀜

  • copy(): 배열이나 하위 배열 내의 값을 명시적으로 복사
print(a2)
a2_sub_copy = a2[:2, :2].copy()
print(a2_sub_copy)
a2_sub_copy[:,1] = 1
print(a2_sub_copy)
print(a2)

>>
[[1 0 1]
 [4 0 6]
 [7 8 3]]
[[1 0]
 [4 0]]
[[1 1]
 [4 1]]
[[1 0 1]
 [4 0 6]
 [7 8 3]]

5. 배열 변환

배열 전치 및 축 변경

print(a2)
print(a2.T)
>>
[[1 0 1]
 [4 0 6]
 [7 8 3]]
[[1 4 7]
 [0 0 8]
 [1 6 3]]
print(a3)
>>
[[[1 2 3]
  [4 5 6]
  [7 8 9]]

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

 [[1 2 3]
  [4 5 6]
  [7 8 9]]]
print(a3.T)
>>
[[[1 1 1]
  [4 4 4]
  [7 7 7]]

 [[2 2 2]
  [5 5 5]
  [8 8 8]]

 [[3 3 3]
  [6 6 6]
  [9 9 9]]]
print(a2)
print(a2.swapaxes(1,0))
>>
[[1 0 1]
 [4 0 6]
 [7 8 3]]
[[1 4 7]
 [0 0 8]
 [1 6 3]]
print(a3)
>>
[[[1 2 3]
  [4 5 6]
  [7 8 9]]

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

 [[1 2 3]
  [4 5 6]
  [7 8 9]]]
print(a3.swapaxes(0,1))
>>
[[[1 2 3]
  [1 2 3]
  [1 2 3]]

 [[4 5 6]
  [4 5 6]
  [4 5 6]]

 [[7 8 9]
  [7 8 9]
  [7 8 9]]]
print(a3.swapaxes(1,2))
>>
[[[1 4 7]
  [2 5 8]
  [3 6 9]]

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

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

배열 재구조화

  • reshape(): 배열의 형상을 변경
n1 = np.arange(1, 10)
print(n1)

print(n1. reshape(3,3))
>>
[1 2 3 4 5 6 7 8 9]
[[1 2 3]
 [4 5 6]
 [7 8 9]]
  • newaxis(): 새로운 축 추가
print(n1)

print(n1[np.newaxis, :5])
print(n1[:5, np.newaxis])

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

row에 newaxis 했으니까 대괄호 안에 대괄호

col에 newaxis 했으니까 칼럼으로 표현

 

배열의 크기 변경

n2 = np.random.randint(0, 10 , (2, 5))
print(n2)
>>
[[6 6 6 1 4]
 [8 8 3 1 5]]
n2. resize((5,2))
print(n2)
>>
[[6 6]
 [6 1]
 [4 8]
 [8 3]
 [1 5]]
  • 배열 크기를 증가하면 남은 공간은 0으로 채워짐
n2.resize((5,5))
print(n2)
>>
[[6 6 6 1 4]
 [8 8 3 1 5]
 [0 0 0 0 0]
 [0 0 0 0 0]
 [0 0 0 0 0]]
  • 배열 크기를 줄이면 포함되지 않는 값들은 삭제된다
n2.resize((3,3))
print(n2)
>>
[[6 6 6]
 [1 4 8]
 [8 3 1]]

배열 추가

  • append(): 배열의 끝에 값 추가
a2 = np.arange(1,10).reshape(3,3)
print(a2)
b2 = np.arange(10, 19).reshape(3,3)
print(b2)
>>
[[1 2 3]
 [4 5 6]
 [7 8 9]]
[[10 11 12]
 [13 14 15]
 [16 17 18]]
  • aixs 지정이 없으면 1차원 배열 형태로 변형되어 결합
c2 = np.append(a2, b2)
print(c2)
>> [ 1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18]
  • axis = 0으로 지정하면 shape[0]을 제외한 나머지 shape은 같아야 함 
c2 = np.append(a2, b2, axis = 0)
print(c2)
>>
[[ 1  2  3]
 [ 4  5  6]
 [ 7  8  9]
 [10 11 12]
 [13 14 15]
 [16 17 18]]
  • axis = 1으로 지정하면 shape[1]을 제외한 나머지 shape은 같아야 함 
c2 = np.append(a2, b2, axis = 1)
print(c2)
>>
[[ 1  2  3 10 11 12]
 [ 4  5  6 13 14 15]
 [ 7  8  9 16 17 18]]

 

배열 연결

  • concatenate(): 튜플이나 배열의 리스트를 인수로 사용해 배열 연결
a1 = np.array([1, 3 ,5])
b1 = np.array([2, 4, 6])
np.concatenate([a1, b1])
>> array([1, 3, 5, 2, 4, 6])
c1 = np.array([7 ,8 , 9])
np.concatenate([a1, b1, c1])
>> array([1, 3, 5, 2, 4, 6, 7, 8, 9])
a2 = np.array([[1, 2, 3], 
              [4, 5, 6]])
np.concatenate([a2, a2], axis = 1)
>>
array([[1, 2, 3, 1, 2, 3],
       [4, 5, 6, 4, 5, 6]])
  • vstack(): 수직 스택(vertical stack), 1차원으로 연결
np.vstack([a2, a2])
>>
array([[1, 2, 3],
       [4, 5, 6],
       [1, 2, 3],
       [4, 5, 6]])
  • hstack(): 수평 스택(horizontal stack), 2차원으로 연결
np.hstack([a2, a2])
>> 
array([[1, 2, 3, 1, 2, 3],
       [4, 5, 6, 4, 5, 6]])
  • dstack(): 깊이 스택(depth stack), 3차원으로 연결
np.dstack([a2, a2])
>>
array([[[1, 1],
        [2, 2],
        [3, 3]],

       [[4, 4],
        [5, 5],
        [6, 6]]])
  • stack(): 새로운 차원으로 연결
np.stack([a2, a2])
>>
array([[[1, 2, 3],
        [4, 5, 6]],

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

 

배열 분할

  • split(): 배열 분할
a1 = np.arange(0, 10)
print(a1)
b1, c1 = np.split(a1, [5])
print(b1, c1)
>>
[0 1 2 3 4 5 6 7 8 9]
[0 1 2 3 4] [5 6 7 8 9]
  • vsplit(): 수직 분할, 1차원으로 분할
a2 = np.arange(1, 10).reshape(3,3)
print(a2)
b2, c2 = np.vsplit(a2, [2])
print(b2)
print(c2)
>>
[[1 2 3]
 [4 5 6]
 [7 8 9]]
[[1 2 3]
 [4 5 6]]
[[7 8 9]]
b2, c2 = np.vsplit(a2, [1])
print(b2)
print(c2)
>>
[[1 2 3]]
[[4 5 6]
 [7 8 9]]

-> 1 기준으로 나누기

  • hsplit(): 수평 분할, 2차원으로 분할
a2 = np.arange(1, 10).reshape(3,3)
print(a2)
b2, c2 = np.hsplit(a2, [2])
print(b2)
print(c2)
>>
[[1 2 3]
 [4 5 6]
 [7 8 9]]
[[1 2]
 [4 5]
 [7 8]]
[[3]
 [6]
 [9]]
  • dsplit(): 깊이 분할, 3차원으로 분할
a3 = np.arange(1, 28).reshape(3,3,3)
print(a3)
b3, c3 = np.dsplit(a3, [2])
print(b3)
print(c3)
>>
[[[ 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]]]
[[[ 1  2]
  [ 4  5]
  [ 7  8]]

 [[10 11]
  [13 14]
  [16 17]]

 [[19 20]
  [22 23]
  [25 26]]]
[[[ 3]
  [ 6]
  [ 9]]

 [[12]
  [15]
  [18]]

 [[21]
  [24]
  [27]]]

참고 영상

https://youtu.be/mirZPrWwvao

 

'STUDY' 카테고리의 다른 글

[DACON] Data Leakage  (0) 2023.04.03
[A/B Testing] Overview of A/B Testing  (0) 2023.03.21
[Python] Numpy (배열 연산 / 배열 입출력)  (0) 2023.02.12
[Python] Numpy(배열 생성)  (0) 2023.02.12
[Seaborn Tutorial] An introduction to seaborn  (0) 2023.02.08