NAN/Python

[NumPy_5] 난수 / 고유 항목 다루기 / 행렬 전치 / 배열 뒤집기 재구성

onddd 2021. 6. 30. 23:22
728x90

 

난수 생성

 


 

기계 학습 알고리즘을 구성하고 평가할 때 난수 생성은 중요한 역할을 한다.

 

인공 신경망의 가중치를 무작위로 초기화한다거나, 데이터를 무작위 세트로 분할하거나, 데이터 세트를 무작위로

 

셔플 하는 등 난수를 생성하는 일은 필수적이라고 할 만큼 많이 사용된다.

 


 

np.random.randint( )

 

 

 

 기본 형태 

 np.random.randint(low, high, size=None) 

 

low : [선택 사항] int 분포에서 가져올 가장 작은 정수 값 지정 , 생략 시 0부터 high 미만의 정수 반환

high : int 분포에서 가져올 가장 큰 정수 입력

size : [선택 사항] int or int (tuple) 입력, 출력 개수 혹은 shape 결정 기본 값은 None으로 단일 값이 반환

 

print(np.random.randint(2, size=10))

[1 0 1 0 1 1 1 1 1 0]

print(np.random.randint(5, size=(2,4)))

[[3 3 2 2]
 [2 3 1 1]]

 

low , high 선택 시 ~이상 ~ 미만이 적용되어 low이상 high 미만 값이 적용된다.

 

 


 

np.random.rand( )

 

 

 기본 형태 

 np.random.rand(d0, d1,... dn) 

 

d0, d1, dn : [선택 사항] 반환할 배열의 shape를 int로 입력, 미기재 시 단일 값으로 반환 (size와 동일)

 

 

print(np.random.rand(3, 2))
[[0.76471719 0.05417888]
 [0.09713495 0.93847261]
 [0.43437567 0.26996139]]

 

입력한 값에 따라 shape를 반환하는데, 이때 반환 값은 0 이상 1 미만의 값으로 이루어진다.

 

 


 

np.random.randn( )

 

 

 

 기본 형태 

 np.random.randn(d0, d1,,, dn) 

 

d0, d1, dn : [선택 사항] 반환할 배열의 shape를 int로 입력, 미기재 시 단일 값으로 반환 (size와 동일)

 

 

print(np.random.randn(2,4))

[[ 0.27379276  0.23201572 -0.83806599 -1.55740584]
 [-3.01155814 -2.45372117 -0.39718678  0.21331688]]

 

np.random.randn( )는 표준 정규 분포를 따르는 샘플 값을 반환한다.

 

naver 표준정규분포 정의

 


 

np.random.shuffle( )

 

 

 

 기본 형태 

 np.random.shuffle(x) 

 

 

x : 섞일 배열 혹은 리스트를 의미

 

arr = np.arange(10)
np.random.shuffle(arr)
print(arr)

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

 

np.random.shuffle( )은 배열을 무작위로 섞어 제자리에서 시퀀스를 수정한다.

 

이 메서드는 다차원 배열의 첫 번째 축을 따른 배열만 섞기 때문에 하위 배열 간의 순서는 변경되지만

 

그 안의 내용은 동일하게 유지된다.

 

arr = np.arange(9).reshape((3,3))
np.random.shuffle(arr)
print(arr)

[[0 1 2]
 [6 7 8]
 [3 4 5]]
 
 # 하위 배열 행의 순서는 섞였지만 열은 그대로 유지

 


 

np.random.choice( )

 

 

 

 기본 형태 

 np.random.choice(a, size=None, replace = True, p = None) 

 

 

a : int 또는 1차원 배열. int이면 임의 샘플이 a = np.arrange(a)인 것처럼 생성된다.

size : [선택 사항] int 또는 int (tuple)

  • int가 입력되면 반환 값의 size, tuple이 입력되면 shape로 간주해(m, n, k) 일 때 m*n*k개의 샘플이 반환된다 기본값은 None으로 이 경우 단일 값이 반환됨

replace : [선택 사항] boll. 샘플의 중복 여부

p : [선택 사항] 1차원 배열 a의 각 항목과 관련된 확률, 지정되지 않은 경우 샘플은 a의 모든 항목에 대해 균일한 분포

 

 

# np.arange(5)에서 3개의 샘플을 각각의 확률에 맞춰 생성

print(np.random.choice(5, 3, p=[0.1, 0, 0.3, 0.6, 0]))

[0 2 2]

zoo = ['rabbit','lion','elephant','monkey']
print(np.random.choice(zoo, 5, p = [0.5, 0.1, 0.1, 0.3]))

['elephant' 'monkey' 'rabbit' 'elephant' 'monkey']

 



고유 항목 및 개수 얻기

 

 

np.unique( )

 

 

 기본 형태 

 np.unique( arr,return_index = False, return_inverse = False, return_count = False, axis = None ) 

 

 

유니크 함수는 배열의 정렬된 고유 값을 오름차순으로 나열하여 반환하는 함수이다.

 

고유 값을 반환 하기 때문에 중복되는 요소를 없애고 하나씩만 남은 배열로 만들어준다.

 

고유 값 외에도 세가지 선택적 출력을 포함하고 있다.

 

  • arr: 입력 배열 axis가 지정되지 않으면 1차원으로 반환한다.
  • return_index : [선택 사항] True 인 경우 각 고유 값이 처음 나타나는 arr의 인덱스도 같이 반환한다.
  • return_inverse : [선택 사항] True 인 경우 arr로 재구성할 때 사용할 수 있도록 arr을 반환 배열 인덱스로 나태 내 같이 반환한다.
  • return_count : [선택 사항] True인 경우 각 고유 값이 arr에 나타나는 횟수도 함께 반환한다.
  • axis : [선택 사항] 작업할 축을 int 형태로 입력한다, None이면 1차원 배열로 반환

 

import numpy as np

a = np.array([11,11,12,13,14,15,16,17,13,16,15])

unique_a = np.unique(a)
print(unique_a)

[11 12 13 14 15 16 17]

 

선택 사항을 제외하여 실행한 결과로 중복되는 요소 값을 제외하여 출력됐다.

 

import numpy as np

a = np.array([11,11,12,13,14,15,16,17,13,16,15])

unique_a = np.unique(a,True,True,True)
print(unique_a)

(array([11, 12, 13, 14, 15, 16, 17]), array([0, 2, 3, 4, 5, 6, 7]), array([0, 0, 1, 2, 3, 4, 5, 6, 2, 5, 4]), array([2, 1, 2, 1, 2, 2, 1]))

 

위에 언급한 선택 사항을 모두 입력하면 예시와 같이 그 값을 포함하여 새로운 배열로 반환을 하는데,

 

True로 표현을 하게 되면 순차적으로 실행이 되기 때문에 그중 원하는 값만을 추가하고자 한다면 

 

return_index = True와 같이 작성해 사용하면 된다.

 

2차원 배열에서도 마찬가지로 사용이 가능하지만 axis가 입력되지 않으면 1차원 배열로 반환을 한다.

 

또, 2차원 배열은 행, 열의 구분이 있기 때문에 고유 행을 구하기 위해서는 axis = 0 

 

고유 열을 구하기 위해서는 axis = 1로 지정하여 반환받아 사용한다.

 

arr2 = np.array([[1,2,3,4],
                 [5,6,7,8],
                 [9,10,11,12],
                  [1,2,3,4]])
arr2 = np.unique(arr2,axis=0)
print(arr2)

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

 


 

행렬의 전치, 재구성

 

 

 기본 형태 

 numpy.transpose(a, axes =None) 

 

  • a : 입력 배열
  • axes : [선택 사항] 튜플 또는 정수 리스트로 axes를 지정할 경우 [0,1,... , N-1]의 순열을 포함하는 튜플 또는              리스트여야 한다. N = a의 축 개 수, 지정하지 않은 경우 기본 값은 range(a.ndim)[::-1]이며 축 순서를                  반대로 반환한다.

 

행렬의 전치란 특정 행렬의 행과 열을 맞바꾸는 것을 의미한다.

 

arr = np.arange(4).reshape((2,2))
print(arr)

[[0 1]
 [2 3]]
 
 print(np.transpose(arr))
 [[0 2]
 [1 3]]

 

간단한 형태로 코드를 실행하면 행과 열의 위치가 변환된 것을 쉽게 알 수 있다.

 

arr = np.ones((1,2,3))
print(arr)
print()
print(np.transpose(arr,(1,0,2)).shape)

[[[1. 1. 1.]
  [1. 1. 1.]]]

(2, 1, 3)

#axes를 입력한 경우 반환 값

 

 

이제 프로그래밍에 어느 정도 익숙해진 분들이라면 알다시피, 개발자들은 타이핑을 길게 치는 걸 좋아하지 않는다.

 

다른 함수들에 비해 비교적 길이가 긴 transpose() 메서드는 T로 대체할 수 있다.

 

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

print(arr.T)
[[1. 3.]
 [2. 4.]]

 


배열 뒤집기

 

 

transpose() 메서드가 행렬의 위치를 바꾸는 함수였다면

 

np.flip( )은 배열의 내용을 축을 기준으로 뒤집어주는 함수이다. 축을 기준으로 하는 함수이지만,

 

축을 지정하지 않는다면 배열 전체를 뒤집어 반환한다.

 

#1차원 배열 뒤집기

arr = np.array([1,2,3,4,5,6,7,8])
print(np.flip(arr))
#2차원 배열 뒤집기

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

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

 

2차원 배열은 축을 지정하여 행, 열을 기준으로 뒤집을 수 있다.

 

# 행 기준으로 뒤집기
arr1 = np.array([[1,2,3,4],
                 [5,6,7,8],
                 [9,10,11,12],
                  [1,2,3,4]])
print(np.flip(arr1,axis=0))

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

# 열 기준으로 뒤집기

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

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

 


1차원 배열로 구성하기

 

 

flatten( )

 

 

 기본 형태 

 nmp.faltten(order='C') 

  • order : [선택 사항] C, F, A, K 중 선택, 기본 값은 C로 행을 우선, F는 열을 우선으로 평면화 한다.

 

arr = np.array([[1,2],[3,4]])
print(arr)
print(arr.flatten(order='F'))

[[1 2]
 [3 4]]
[1 3 2 4]

 


 

ravel( )

 

 

 기본 형태 

 np.ravel(a, order='C') 

  • a : 입력 배열
  • order : [선택 사항] C, F, A, K 중 선택, 기본 값은 C로 행을 우선, F는 열을 우선으로 평면화 한다. 1

 

arr = np.array([[1,2,3],[4,5,6]])
print(arr)
print(np.ravel(arr,order='F'))
[[1 2 3]
 [4 5 6]]
[1 4 2 5 3 6]

 

 

두 가지 함수 모두 동일한 기능을 가지고 있지만 프로그래밍 언어에서는 이유 없이 같은 기능을 넣는 경우가 거의 없다.

 

ravel()의 경우 부모 배열을 참조(=view) 하기 때문에 새로 만들어진 배열의 변경 사항이 상위 배열에도 영향을 준다.

 

그렇기 때문에 ravel은 메모리 효율 부분에서 우수하고, flatten()은 copy 방식이기 때문에 원본이 유지가 된다.

 

따라서 뭐가 더 좋다기보다는 각 상황과, 환경에 맞춰 사용하는 게 바람직하다.