3.5 난수 발생과 카운팅
1. 난수 발생과 카운팅
- 파이썬을 이용하여 데이터를 무작위로 섞거나 임의 수(난수)
- 이 기능은 주로 NumPy의 random 서브페키지에서 제공
2. 시드 설정하기
- 컴퓨터 프로그래밍에서 무작위 수는 사실 무작위 수가 아니다.
- 정해진 알고즘에 의해 난수처럼 보이는 수열을 생성
- 이런 시작 숫자를 시드(seed)라고 한다.
- 일단 생성된 난수는 다음번 난수 생성을 위한 시드값이 된다.
- 따라서 시드값은 한 번만 정해주면 된다.
- 시드는 보통 현재 시각등을 이용하여 자동으로 정해지지만 사람이 수동으로 설정할 수 있다.
- 특정한 시드값이 사용되면 그 다음에 만들어지는 난수들은 모두 예특할 수 있음
- 이 책에서는 코드의 결과를 재현하기 위해 항상 시드를 설정한다.
# - 파이썬에서 시드를 설정하는 함수는 seed이다.
# - 인수로는 0과 같거나 큰 정수를 넣어준다.
np.random.seed(0)
- 이렇게 시드 설정 후 넘파이 radnom 서브패키지에 있는 rand함수로 5개 난수 생성해보자
- rand 함수는 0과 1사이의 난수를 발생시키는 함수로 인수로 받은 숫자 횟수 만큼 난수 발생
np.random.rand(5)
#결과
array([0.5488135 , 0.71518937, 0.60276338, 0.54488318, 0.4236548 ])
np.random.rand(10)
#결과
array([0.64589411, 0.43758721, 0.891773 , 0.96366276, 0.38344152,
0.79172504, 0.52889492, 0.56804456, 0.92559664, 0.07103606])
# 이제 시드를 0으로 재설정하고 다시 난수 발생.
np.random.seed(0)
np.random.rand(5)
#결과
array([0.5488135 , 0.71518937, 0.60276338, 0.54488318, 0.4236548 ])
np.random.rand(10)
#결과
array([0.64589411, 0.43758721, 0.891773 , 0.96366276, 0.38344152,
0.79172504, 0.52889492, 0.56804456, 0.92559664, 0.07103606])
- 아까와 같은 숫자가 나온 것을 확인
3. 데이터의 순서 바꾸기
- shuffle 함수 사용
- shuffle 함수도 자체 변환(in-place)함수로 한 번 사용하면 변수의 값이 바뀌므로 주의!
x = np.arange(10)
x
#결과
array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
np.random.shuffle(x)
x
#결과
array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
np.random.shuffle(x)
x
#결과
array([5, 1, 8, 2, 6, 7, 0, 3, 4, 9])
4. 데이터 샘플링
- 이미 있는 데이터 집합에서 일부를 무작위로 선택하는 걸 샘플링이라고 함.
- choice함수 이용
- numpy.random.choice(a, size=None, replace=True, p=None)
- a : 배열이면 원래의 데이터, 정수이면 arange(a) 명령으로 데이터 생성
- size : 정수. 샘플 숫자
- replace : 불리언. True이면 한번 선택한 데이터를 다시 선택 가능
- p : 배열. 각 데이터가 선택될 수 있는 확률
np.random.choice(5, 5, replace=False) # shuffle 명령과 같다.
#결과
array([4, 2, 3, 1, 0])
np.random.choice(5, 3, replace=False) # 3개만 선택
#결과
array([1, 4, 2])
np.random.choice(5, 10) # 반복해서 10개 선택
#결과
array([3, 3, 2, 4, 2, 0, 0, 4, 0, 4])
np.random.choice(5, 10, p=[0.1, 0, 0.3, 0.6, 0]) # 선택 확률을 다르게 해서 10개 선택
#결과
array([3, 3, 3, 2, 3, 2, 3, 3, 3, 0])
5. 난수 생성
- random 서브패키지는 이외에도 난수 생성하는 다양한 함수 제공
- 그 중 가장 간단하고 많이 사용되는 3가지 함수
- rand : 0부터 1사이의 균일 분포
- randn : 표준 정규 분포
- randint : 균일 분포의 정수 난수
- rand 함수는 0부터 1사이에서 균일한 확률 분포로 실수 난수 생성
np.random.rand(10)
#결과
array([0.6228461 , 0.67365963, 0.971945 , 0.87819347, 0.50962438,
0.05571469, 0.45115921, 0.01998767, 0.44171092, 0.97958673])
np.random.rand(3, 5)
#결과
array([[0.35944446, 0.48089353, 0.68866118, 0.88047589, 0.91823547],
[0.21682214, 0.56518887, 0.86510256, 0.50896896, 0.91672295],
[0.92115761, 0.08311249, 0.27771856, 0.0093567 , 0.84234208]])
- randn함수는 기댓값이 0이고 표준편차가 1인 표준 정규 분포
np.random.randn(10)
# 결과
array([ 0.99982969, 0.43103415, -0.65091287, -1.49874039, -1.23063497,
0.19400719, -0.99838235, -0.3676376 , 1.73719932, 0.59361275])
np.random.randn(3, 5)
# 결과
array([[-0.54236358, -1.71967238, -0.57890879, 1.42694855, 0.27699691],
[ 0.78966713, 0.32207411, 0.70039238, 0.38871663, -0.04126386],
[ 0.29588432, -0.42527999, 1.72763912, -0.86835257, -0.82097758]])
- randint 함수는 다음과 같은 인수를 가진다.
- numpy.random.randint(low, high=None, size=None)
- 만약 high를 입력하지 않으면 0과 low사이를 숫자를,
- high를 입력하면 low와 high는 사이의 숫자를 출력
- size는 난수의 숫자이다.
np.random.randint(10, size=10)
# 결과
array([9, 0, 9, 6, 5, 3, 1, 8, 0, 4])
np.random.randint(10, 20, size=(3, 5))
# 결과
array([[19, 16, 15, 17, 18],
[18, 19, 12, 18, 16],
[16, 19, 11, 16, 18]])
6. 정수 데이터 카운팅
- 이렇게 발생시킨 난수가 실수값이면 히스토리그램 등을 사용하여 분석
- 나중에 시각화 부분에서 히스토그램을 배울 예정
- 만약 난수가 정수값이면 unique 명령이나 bincount 명령으로 분석
- unique 함수는 데이터에서 중복된 값을 제거하고 중복되지 않는 값의 리스트를 출력
-return_counts 인수를 True로 설정하면 각 값을 가진 데이터 갯수도 출력한다.
np.unique([11, 11, 2, 2, 34, 34])
# 결과
array([ 2, 11, 34])
a = np.array(['a', 'b', 'b', 'c', 'a'])
index, count = np.unique(a, return_counts=True)
index
# 결과
array(['a', 'b', 'c'], dtype='<U1')
count
# 결과
array([2, 2, 1], dtype=int64)
- 그러나 unique 함수는 데이터에 존재하는 값에 대해서만 갯수를 세므로 데이터 값이 나올 수 있음에도 불구하고 데이터가 하나도 없는 경우에는 정보를 주지 않는다.
- 예를 들어 주사위를 10번 던졌는데 6이 한 번도 나오지 않으면 이 값을 0으로 세어주지 않는다.
- 따라서 데이터가 주사위를 던졌을 때 나오는 수처럼 특정 범위안의 수인 경우에는
- bimcount 함수에 minlength 인수를 설정하여 쓴느 것이 더 편리
- bincount 함수는 0 부터 minlength -1 까지의 숫자에 대해 각각 카운트를 한다.
- 데이터가 없을 경우에는 카운트 값이 0이 된다.
np.bincount([1, 1, 2, 2, 2, 3], minlength=6)
#결과
array([0, 2, 3, 1, 0, 0], dtype=int64)
'😀 기초 > 넘파이(NumPy)' 카테고리의 다른 글
3장 배열의 연산(3.3) (0) | 2022.01.25 |
---|---|
3장 넘파이 배열의 생성과 변형(3.2) (0) | 2022.01.25 |
3장 넘파이 배열 프로그래밍(3.1) (0) | 2022.01.24 |
NumPy 한번에 끝내기 (0) | 2022.01.18 |