[Python] 데이터 사이언스 스쿨 - 3.5 난수 발생과 카운팅

Updated:

데이터 사이언스 스쿨 자료를 토대로 공부한 내용입니다.

실습과정에서 필요에 따라 내용의 누락 및 추가, 수정사항이 있습니다.


3.5 난수 발생과 카운팅

import numpy as np
# 시드 설정하기
np.random.seed(0)

# 난수 발생
np.random.rand(3)
array([0.5488135 , 0.71518937, 0.60276338])
  • np.random.seed()로 시드 번호를 설정하면 난수 발생시 같은 결과를 출력 가능하다.
# suffle - 데이터의 순서 바꾸기
x = np.arange(10)

np.random.shuffle(x)
x
array([8, 6, 4, 0, 2, 5, 9, 1, 7, 3])

데이터 샘플링

넘파이에서 데이터 샘플링은 np.random.choice() 함수를 사용한다.

numpy.random.choice(a, size = None, replace = True, p = None)
  • a: 배열 입력, 정수 입력시 np.arange(a)로 인식

  • size: 추출할 샘플 갯수

  • replace: 복원 추출 여부

  • p: 배열의 각 데이터가 추출 될 확률

# shuffle과 같음
np.random.choice(5,5,replace=False)
array([3, 1, 2, 4, 0])
# 일부 추출
np.random.choice(5,2,replace=False)
array([4, 2])
# 복원 추출
np.random.choice(5,7)
array([0, 1, 4, 3, 0, 3, 0])
# 확률을 부여해서 복원 추출
np.random.choice(5,10, p = [0.1, 0, 0.4, 0.5, 0])
array([3, 3, 2, 3, 2, 3, 2, 3, 3, 2])

난수 생성

넘파이에서 난수를 생성하는 여러 함수가 있다.

그 중 일부만 정리해보았다.

  • np.rand(): uniform 분포에서 난수 즉, 0 ~ 1 사이 값을 생성한다.

  • np.randn(): standard normal 분포에서 난수를 생성한다.

  • np.ranint(): 0 ~ 정수 사이 uniform 분포에서 난수를 생성한다.

# 균일 분포
print(np.random.rand(5))
print(np.random.rand(2,2))
[0.26455561 0.77423369 0.45615033 0.56843395 0.0187898 ]
[[0.6176355  0.61209572]
 [0.616934   0.94374808]]
# 표준 정규 분포
print(np.random.randn(5))
print(np.random.randn(2,2))
[-1.078278    1.39547227  1.78748405 -0.56951726  0.17538653]
[[-0.46250554 -1.0858006 ]
 [ 0.63973599 -0.38586334]]
# 균일 분포2
print(np.random.randint(10, size=5)) # 0 ~ 10 사이
print(np.random.randint(10, 20, size=5)) # 10 ~ 20 사이
print(np.random.randint(10, 20, size=(2, 2))) # 10 ~ 20 사이 행렬
[5 9 4 4 6]
[14 14 13 14 14]
[[18 14]
 [13 17]]

연습 문제 3.5.1

  1. 동전을 10번 던져 앞면(숫자 1)과 뒷면(숫자 0)이 나오는 가상 실험을 파이썬으로 작성한다.

  2. 주사위를 100번 던져서 나오는 숫자의 평균을 구하라.

# 1. 동전 실험
print(np.random.randint(0, 2, size=10))
[1 1 1 1 0 1 1 1 1 0]
# 2. 주사위 평균
dice = np.random.randint(1,7, size = 100)
print(np.mean(dice))
3.32

연습 문제 3.5.2

가격이 10,000원인 주식이 있다.

이 주식의 일간 수익률(%)은 기댓값이 0%이고 표준편차가 1%인 표준 정규 분포를 따른다고 하자.

250일 동안의 주가를 무작위로 생성하라.

price = np.ones(250) * 10000
x = np.random.randn(250)

# 전일 종가대비로 작성하지 않고 다음과 같은 수식으로 계산
# 10,000원 + (10,000원 x 수익률)
price + (price * x / 100)
array([ 9922.42376466,  9872.95150015, 10096.93967082,  9882.68765949,
       10194.36211856,  9958.63810192,  9925.25451886, 10192.29420265,
       10148.05147914, 10186.75589604, 10090.60446583,  9913.87743149,
       10191.00649531,  9973.1996629 , 10080.24563958, 10094.72519678,
        9984.49899069, 10061.40793703, 10092.22066716, 10037.64255312,
        9890.05992094, 10029.82381742, 10132.63858967,  9930.54321403,
        9985.03654597,  9956.48464483, 10184.92637285, 10067.2294757 ,
       10040.74618362,  9923.00839256, 10053.92491913,  9932.56673393,
       10003.18305583,  9936.41539216, 10067.64332949, 10057.65908166,
        9979.17012444, 10039.60067127,  9890.69384913,  9850.87424073,
       10043.93917013, 10016.66734954, 10063.50314369, 10238.31447749,
       10094.4479487 ,  9908.71777746, 10111.70162881,  9868.40925895,
        9953.84153952,  9993.17583947, 10171.33427216,  9925.5245178 ,
        9917.35614613,  9990.15474756,  9933.65217136, 10112.66359221,
        9892.00684916,  9885.25313476,  9956.21799553,  9950.19675493,
       10192.95320538, 10094.94208069, 10008.75512414,  9877.45644812,
       10084.43629764,  9899.97846526,  9845.52289032, 10118.80297924,
       10031.69426119, 10092.08588238, 10031.87276529, 10085.68306119,
        9934.89744067,  9896.57571582, 10068.15945183,  9919.65903358,
        9931.04502222,  9954.44674965, 10001.7479159 ,  9964.60060887,
        9862.50487066,  9935.63815972,  9777.65968478, 10062.5231451 ,
        9839.79423444,  9889.56166606, 10005.21650793,  9926.04370036,
       10154.30145954,  9870.71430903, 10026.70508693,  9996.07171818,
        9883.19065023, 10052.32766605,  9982.84536688, 10077.17905512,
       10082.3504154 , 10216.32359493, 10133.65279494,  9963.08181621,
        9976.06208224, 10109.96595959, 10065.52637307, 10064.01315261,
        9838.30439557,  9997.56738756,  9926.19690908, 10027.9924599 ,
        9990.18496104, 10091.01789081, 10031.72182152, 10078.63279621,
        9953.35809033,  9905.55537441,  9958.99503068,  9998.29795861,
       10037.91517356, 10225.93089507,  9995.77428483,  9904.40549995,
        9965.40182243,  9953.64040254, 10048.14814738,  9845.92029856,
       10006.32619942, 10015.6506538 , 10023.21810362,  9940.2683931 ,
        9976.20782703,  9857.5939091 ,  9950.66801166,  9945.7138524 ,
       10041.60500463,  9884.38175682, 10078.11981017, 10149.44845445,
        9793.0014975 , 10042.62587308, 10067.6908035 ,  9936.25629744,
        9960.27281857,  9986.71194224,  9970.22091206,  9969.0987031 ,
        9832.39961937, 10115.23315648, 10107.9618592 ,  9918.66357408,
        9853.35756722, 10052.10648765,  9942.42120302, 10014.19531633,
        9968.06715829, 10069.15387511, 10069.47491437,  9927.44026215,
        9861.66360446,  9841.70616027, 10061.03793791,  9881.11407422,
        9949.31836457,  9940.36859615,  9994.74327037,  9806.37201942,
       10018.87785968, 10052.38910238, 10008.8422087 ,  9968.91138283,
       10009.74001663, 10039.90463456,  9722.74072436, 10195.59123083,
       10039.00933227,  9934.75914176,  9960.90466248, 10049.37417773,
        9988.3896061 ,  9796.93155322, 10206.44928614,  9988.94593428,
       10102.01727117,  9930.79501522, 10153.63770542, 10028.63436889,
       10060.88438345,  9895.47466339, 10121.11452897, 10068.98181645,
       10130.18462296,  9937.19124404,  9951.89728815, 10230.39166977,
        9893.99841773,  9986.40502993, 10113.68913626, 10009.77249677,
       10058.29536798,  9960.05509707, 10037.00558878,  9869.34731483,
       10165.81306796,  9988.18359549,  9931.9821796 , 10066.6383082 ,
        9953.92802126,  9866.57415286,  9865.32824942, 10069.37731527,
        9984.04265619,  9986.62984403, 10107.7743806 ,  9887.31741912,
        9926.93222471,  9961.51201908, 10009.43515893,  9995.78285487,
        9971.31128076,  9993.83735979,  9989.26947237,  9928.03956114,
        9918.70070114, 10027.45163577,  9910.9084917 ,  9884.26447408,
        9968.77077489,  9984.23329838, 10225.67234973,  9929.52997241,
       10094.3260725 , 10074.71883342,  9881.10550448, 10077.32529774,
        9881.61193598,  9734.0827762 , 10060.63195244,  9824.41094166,
       10045.09344618,  9931.59891023, 10165.95507962, 10106.85093993,
        9954.66141961,  9931.2162389 ,  9878.59225969,  9955.90773677,
        9971.96445048,  9963.53064556, 10015.67038553, 10057.85214977,
       10034.9654457 ,  9923.58560761])
  • 주석에 기입하였듯이 전일 종가대비로 주가를 생성하지 않고 다음과 같은 수식으로 계산하였다.

  • 10,000원 + (10,000원 x 수익률)

  • 종가대비로 주가를 생성한다면 for문을 이용해서 반복시마다 1번 난수를 생성하고 전 가격과 연산하면 될 듯 하다.

정수 데이터 카운팅

# 정수 데이터 카운팅
np.unique([11, 11, 2, 2, 34, 34])
array([ 2, 11, 34])
  • np.unique()는 배열의 중복 없이 어떠한 값이 있는지 찾아준다.

  • 집합 set()과 비슷한 느낌이다.

# 데이터와 그에 따른 갯수
x = np.array(['a', 'b', 'b', 'c', 'a'])
index, count = np.unique(x, return_counts=True)

print(index, count)
['a' 'b' 'c'] [2 2 1]
  • np.unique()에 return_counts를 True로 옵션을 부여하면 값의 종류와 종류별 갯수를 확인 가능하다.
# 주사위 나온 눈의 개수
dice = np.random.randint(1,7, size = 5)
print(dice)

index, count = np.unique(dice, return_counts=True)
print(index, count)

print(np.bincount(dice, minlength=7))
[2 1 5 2 3]
[1 2 3 5] [1 2 1 1]
[0 1 2 1 0 1 0]
  • np.bincount()는 실제로 데이터가 없어도 0으로 갯수를 출력해준다.

  • 만약 주사위를 5번 굴렸다면 적어도 1개의 주사위 눈은 나오지 않는다.

  • 위 예시처럼 minlength를 7로 주면 0부터 6까지 7개의 숫자에 대한 갯수는 설령 0일지어도 무조건 출력한다.

Leave a comment