ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • Python 기초 공부 - 7 (numpy)
    Programming/Python 2021. 3. 9. 18:31
    반응형

    numpy 계산만 진행합니다.

    # flask : 웹 서버 기능, 5000번 포트로 서비스
    
    import matplotlib # 시각화 패키지
    import numpy as np # 클래스로 구성되어 있다. as : 별칭
    
    print(np.__version__) # __는 상위 오브젝트가 가지고 있는 속성이라는 의미
    
    def pprint(arr):
        print("type : {}".format(type(arr)))
        print("shape : {}, dimension : {}, dtype : {}".format(arr.shape, arr.ndim, arr.dtype)) # 차수 3개다, 차원 1차원이다, 데이터 타입 숫자의 default는 int32
        print("Array's Data : \n",arr)
        
    arr = [1.0,2.0,3.0] # list
    a = np.array([1,2,3]) # ndarray : numpy의 기본 데이터 배열 , 매개변수는 리스트로 들어간다
    pprint(a)

    1.16.4
    type : <class 'numpy.ndarray'>
    shape : (3,), dimension : 1, dtype : int32
    Array's Data : 
     [1 2 3]

    # 인스턴스 상태에서 ndarray를 만들어보자
    a = np.array([0,1,2,3,4,5,6,7,8,9])
    print(id(a)) # 메모리 주소값 확인
    print(a.size) # 데이터 갯수
    print(a.astype(np.float32)) # astype : 데이터 타입 변경, numpy 행중심, 동질적
    print(a.dtype.itemsize*a.size) # 전체 메모리 사이즈(byte) = 타입 고유의 사이즈 * 차수 수
    
    # iterator
    # range는 list를 만들고, arange는 ndarray를 만든다.
    a = np.arange(100)
    a

    1509824915376
    10
    [0. 1. 2. 3. 4. 5. 6. 7. 8. 9.]
    40
    array([ 0,  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, 28, 29, 30, 31, 32, 33,
           34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50,
           51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67,
           68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84,
           85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99])

     

    # ndarray 초기화 함수
    print( np.zeros( (3,4) ) ) # 0 채워넣기
    print( np.ones( (2,3,4), dtype = np.int16 ) ) # 1채워넣기 3차원[] 2면, 3행, 4열 ]
    print( np.full( (2,2), 7) ) # 2행 x 2열 7로 채워넣기
    print( np.eye(4) ) # 대각 1넣기, 대각행렬 identity 항등원 + 0 * 1
    print( np.empty( (4, 2) ) ) # 쓰레기값...

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

     [[1 1 1 1]
      [1 1 1 1]
      [1 1 1 1]]]
    [[7 7]
     [7 7]]
    [[1. 0. 0. 0.]
     [0. 1. 0. 0.]
     [0. 0. 1. 0.]
     [0. 0. 0. 1.]]
    [[0.00000000e+000 0.00000000e+000]
     [0.00000000e+000 0.00000000e+000]
     [0.00000000e+000 4.62445445e-321]
     [1.24611470e-306 8.90060779e-307]]

    a = np.arange(0, 100, 10)
    indices = [1, 5, -1]
    print(indices)
    b = a[indices] # 리스트를 첨자로 사용
    print(a)
    print(b)

    [1, 5, -1]
    [ 0 10 20 30 40 50 60 70 80 90]
    [10 50 90]

     

    a = np.arange(11, 36)
    print(a)
    a.shape = (5,5) # 행렬은 정상모양을 갖춘 개수로 표현
    print(a)
    print(type(a))
    print(a.dtype)
    print(a.size)
    print(a.shape) # 차수
    print(a.ndim) # 차원
    print(a.nbytes) # 100바이트 = 25개 * 4바이트
    print(a.strides) # 다음 행,열의 데이터는 몇 바이트를 건너뛰는가

    [11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
     35]
    [[11 12 13 14 15]
     [16 17 18 19 20]
     [21 22 23 24 25]
     [26 27 28 29 30]
     [31 32 33 34 35]]
    <class 'numpy.ndarray'>
    int32
    25
    (5, 5)
    2
    100
    (20, 4)

    arr = np.arange(10)
    print(type(arr))
    print(arr)
    print(arr[5])
    print(arr[5:8])
    arr[5:8] = 12
    print(arr[1:6])

    <class 'numpy.ndarray'>
    [0 1 2 3 4 5 6 7 8 9]
    5
    [5 6 7]
    [ 1  2  3  4 12]

    # numpy 첨자생략 불가 [,4] 이런 것 안됨
    
    arr2d = np.array([ [1,2,3], [4,5,6], [7,8,9] ])
    print(arr2d[0]) # 행우선 이니 0행 출력
    print(arr2d[0][2]) # 0행 2열
    print(arr2d[0,2])
    print(arr2d[:2]) # 0,1행
    print(arr2d[:2,1:])
    print(arr2d[:,1:]) # :는 모든 행
    print(arr2d[1,:2])
    print(arr2d[2,:1])
    arr2d[:2, :1] = 0
    arr2d[:2, :1] = 0
    print(arr2d)

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

     

    사람이 데이터를 다루는 것은 입체로 하나, 실제 메모리에는 일렬로 저장

    행렬연산에서의 앞의 행렬열수와 뒤의 행렬 행수를 일치시켜야 행렬곱이 가능하므로,
    행렬곱에서 행렬의 계산 순서를 바꾸면 안됨

    print("스트라이드의 값", np.ones((3,4,5), dtype=np.float64).strides )
    

    스트라이드의 값 (160, 40, 8)

     


    단일데이터가 float64 : 8바이트

    40 = 5열 * 8바이트
    160 = 4행 * 5열 * 8바이트

     

    # 문제
    arr3d = np.array([ [[1,2,3], [4,5,6]], [[7,8,9],[10,11,12]] ]) # 2, 2, 3
    print("첫 면은 = ", arr3d[0])
    print("첫 면의 첫행은 = ", arr3d[0,0])
    print("첫요소는 = ", arr3d[0,0,0])
    
    # 8을 출력해봅시다
    print(arr3d[1,0,1])
    # 12를 출력해봅시다
    print(arr3d[1,1,2])

    첫 면은 =  [[1 2 3]
     [4 5 6]]
    첫 면의 첫행은 =  [1 2 3]
    첫요소는 =  1
    8
    12

    # 백업이 안됨 : 대입하면 같은 주소를 가리키기 때문
    old_values = arr3d # 대입 : 주소를 복사
    arr3d[0] = 42
    print("값의 변경 후")
    print(arr3d,'\n')
    print(" 이전 값으로 복구")
    arr3d = old_values
    print(arr3d,'\n')
    
    # old_values = arr3d.copy() # 값을 복사
    # arr3d[0] = 42
    # print("값의 변경 후")
    # print(arr3d,'\n')
    # print(" 이전 값으로 복구")
    # arr3d = old_values
    # print(arr3d,'\n')
    

    값의 변경 후
    [[[42 42 42]
      [42 42 42]]

     [[ 7  8  9]
      [10 11 12]]] 

     이전 값으로 복구
    [[[42 42 42]
      [42 42 42]]

     [[ 7  8  9]
      [10 11 12]]] 

    값의 변경 후
    [[[42 42 42]
      [42 42 42]]

     [[ 7  8  9]
      [10 11 12]]] 

     이전 값으로 복구
    [[[42 42 42]
      [42 42 42]]

     [[ 7  8  9]
      [10 11 12]]] 

    Z = np.arange(36)
    print(Z,'\n')
    Z = Z.reshape((6,6))
    reshape2 = Z.reshape((2,3,6))
    print(reshape2)

    [ 0  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 28 29 30 31 32 33 34 35] 

    [[[ 0  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 28 29]
      [30 31 32 33 34 35]]]

    arr = np.arange(32).reshape((8,4))
    print(arr,'\n')
    print(arr[[1,5,7,2]],'\n') # 행중심
    print(arr[[-1,-5,-7,-2]],'\n')
    print(arr[ [1,5,7,2], [0,3,1,2] ],'\n')
    
    # fancy 인덱싱
    print(arr[[1,2,5,7]] [:,[0,1,2,3]],'\n')
    print(arr[[1,5,7,2]] [:,[0,3,1,2]])

    [[ 0  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]
     [28 29 30 31]] 

    [[ 4  5  6  7]
     [20 21 22 23]
     [28 29 30 31]
     [ 8  9 10 11]] 

    [[28 29 30 31]
     [12 13 14 15]
     [ 4  5  6  7]
     [24 25 26 27]] 

    [ 4 23 29 10] 

    [[ 4  5  6  7]
     [ 8  9 10 11]
     [20 21 22 23]
     [28 29 30 31]] 

    [[ 4  7  5  6]
     [20 23 21 22]
     [28 31 29 30]
     [ 8 11  9 10]]

     

    arr = []
    for i in range(6):
        ad = []
        for j in range(6):
            ad.append( i*10 + j )
        arr.append(ad)
    print(arr)
    arr = np.array(arr)
    
    # 빨간거
    print(arr[[0,2,5],2]); print()
    
    # 주황색
    print(arr[[0,1,2,3,4],[1,2,3,4,5]]); print()
    
    # 옥색
    print(arr[3:6][:,[0,2,5]])
    

    [[0, 1, 2, 3, 4, 5], [10, 11, 12, 13, 14, 15], [20, 21, 22, 23, 24, 25], [30, 31, 32, 33, 34, 35], [40, 41, 42, 43, 44, 45], [50, 51, 52, 53, 54, 55]]
    [ 2 22 52]

    [ 1 12 23 34 45]

    [[30 32 35]
     [40 42 45]
     [50 52 55]]

     



    # 문제2
    
    # 빨간거
    print(arr[:,2]); print()
    
    # 주황
    print(arr[0,[3,4]]); print()
    
    # 녹
    print(arr[[2,5]][:,[0,2,4]]); print()
    
    # 청녹
    print(arr[4:][:,[4,5]]); print()
    

    [ 2 12 22 32 42 52]

    [3 4]

    [[20 22 24]
     [50 52 54]]

    [[44 45]
     [54 55]]

     

    x = np.array([ [1,2,3], [4,5,6], [7,8,9], [10,11,12] ]) # 4x3
    v = np.array([1,0,1])
    print("타일출력\n")
    vv = np.tile(v,(4,1)) # 화장실 타일처럼 복사시키기
    print(vv,'\n')
    y = x + vv # 4행3열 배열연산[요소별로 연산 +-*/]     배열연산과 행렬연산은 다르다!!!!!!
    print(y,'\n\n')
    # 배열연산은 양쪽 차원이 일치해야한다
    print(x + v,'\n')# 4x3, 1x3 의 연산이 되나? broadcasting! 행이나 열의 수가 같아야!
    print(x + 3)

    타일출력

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

    [[ 2  2  4]
     [ 5  5  7]
     [ 8  8 10]
     [11 11 13]] 


    [[ 2  2  4]
     [ 5  5  7]
     [ 8  8 10]
     [11 11 13]] 

    [[ 4  5  6]
     [ 7  8  9]
     [10 11 12]
     [13 14 15]]

    x = np.arange(6).reshape((3,2))
    print(x)
    # 거듭제곱(행렬곱)
    #x @ x # 앞의 열수와 뒤의 행수가 일치해야 한다
    # (3x2) (3x2)
    
    # 전치행렬
    x@x.T # (3x2) (2x3)
    
    print(np.transpose(x)) # 행렬을 바꾸어준다

    [[0 1]
     [2 3]
     [4 5]]
    [[0 2 4]
     [1 3 5]]

    arr = np.arange(24).reshape((2,3,4)) # 0,1,2
    print(arr)
    print('\n\n\n')
    print(arr.transpose((1,0,2))) # 3x2x4
    print('\n\n\n')
    print(arr.transpose((0,2,1))) # 2x4x3

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

     [[12 13 14 15]
      [16 17 18 19]
      [20 21 22 23]]]




    [[[ 0  1  2  3]
      [12 13 14 15]]

     [[ 4  5  6  7]
      [16 17 18 19]]

     [[ 8  9 10 11]
      [20 21 22 23]]]




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

     [[12 16 20]
      [13 17 21]
      [14 18 22]
      [15 19 23]]]

     

    BOOLEAN INDEXING (TRUE/FALSE)

    names = np.array(['Seoul', 'Daejun', 'chungju', 'seoul', 'chungju', 'Daejun', 'Daejun'])
    data = np.random.randn(7,4)
    print(names == 'Seoul') # 문자열은 대소문자 구분함  # T,F,F,F,F,F,F
    print(data[names=='Seoul']) # True인 것만 출력
    print(data[names=='Seoul', 2:])
    print(data[names=='Seoul', 3])
    print(names != 'Seoul') # F,T,T,T,T,T,T
    print(~(names=='Seoul')) # F,T,T,T,T,T,T
    mask = (names=='Seoul') | (names=='chungju')
    print(mask)
    print(data[mask])

    [ True False False False False False False]
    [[ 0.42095613  0.17597758 -0.05644088 -1.10524404]]
    [[-0.05644088 -1.10524404]]
    [-1.10524404]
    [False  True  True  True  True  True  True]
    [False  True  True  True  True  True  True]
    [ True False  True False  True False False]
    [[ 0.42095613  0.17597758 -0.05644088 -1.10524404]
     [-0.03307741 -0.87156314 -0.52807885  0.60578028]
     [ 1.37052914  1.3105813   0.5604668  -0.30676522]]

    xarr = np.array([1.1, 1.2, 1.3, 1.4, 1.5])
    yarr = np.array([2.1, 2.2, 2.3, 2.4, 2.5])
    cond = np.array([True, False, True, True, False])
    
    print(zip(xarr, yarr, cond)) # zip : 요소별로 데이터를 묶음
    print(list(zip(xarr, yarr, cond)))
    result = [(x if c else y) for x,y,c in zip(xarr, yarr, cond)] # 3항연산자
    print("result = ",result)
    
    result = np.where(cond, xarr, yarr)
    print(result)
    
    arr = np.random.randn(4,4)
    print(arr)
    print(np.where(arr>0, 2, -2))

    <zip object at 0x0000015DC12E0048>
    [(1.1, 2.1, True), (1.2, 2.2, False), (1.3, 2.3, True), (1.4, 2.4, True), (1.5, 2.5, False)]
    result =  [1.1, 2.2, 1.3, 1.4, 2.5]
    [1.1 2.2 1.3 1.4 2.5]
    [[-0.43115124  0.31799955 -0.71370485  0.36621282]
     [-1.67870128  0.91579184 -0.4281239  -2.15582502]
     [-1.22680744 -1.59959683 -0.29502866  0.04495333]
     [ 0.55818941  0.20412896 -0.02008031  0.1374442 ]]
    [[-2  2 -2  2]
     [-2  2 -2 -2]
     [-2 -2 -2  2]
     [ 2  2 -2  2]]

    # 문제 : 다음 데이터를 이용하여
    # 두개 다 참일 때는 0,
    # cond1이 참일 때는 1,
    # cond2가 참일 때는 2
    # 그 외일 때는 3으로 처리하여 출력하도록 하시오
    
    result = []
    cond1 = np.array([1,0,1,1,0,0,1], dtype=bool)
    cond2 = np.array([0,1,1,1,0,1,1], dtype=bool)
    
    # 조건문으로 하면 4가지
    for i in range(len(cond1)):
        if(cond1[i] and cond2[i]):
            result.append(0)
        elif cond1[i]:
            result.append(1)
        elif cond2[i]:
            result.append(2)
        else:
            result.append(3)
            
    # where로 풀면
    result = np.where(cond1 & cond2, 0, np.where(cond1, 1, np.where(cond2, 2,3)))
    
    # 수식을 이용하면
    result = 1*(cond1&~cond2) + 2*(cond2&~cond1) + 3*~(cond1|cond2)
    
    # 내가 해본 것은
    result = [(0 if (a&b)|(~(a|b)) else (1 if a else (2 if b else 3)) )  for a,b in zip(cond1,cond2)]
    print(result)

    [1, 2, 0, 0, 0, 2, 0]

    x = np.arange(1, 10001)
    y = np.arange(10001, 20001)
    z = np.zeros_like(x) # 파라메터[다른 행렬]와 같은 사이즈로 초기화
    
    for i in range(10000):
        z[i] = x[i] + y[i]
    print(z)

    [10002 10004 10006 ... 29996 29998 30000]

     

    a = np.array([1,2,3,4])
    b = np.array([4,2,2,4])
    print(np.all(a==b)) # 전체가 참일 때 참
    print(np.any(a==b)) # 하나라도 참이면 참
    print(np.exp(a)) # 지수함수( 자연대수 : 2.718)

    False
    [ 2.71828183  7.3890561  20.08553692 54.59815003]


    선형대수 : 문제를 선형으로 해결하자 => 비선형도 잘게 나누면 선형

     

    행렬의 종류
    - 정방행렬 : 정사각형(행, 열의 수가 같은 행렬)
    - 대칭행렬 : 우상단과 좌하단이 같은 것
    - 대각행렬 : scale을 변화시키는 요소
    - 단위행렬(identity) :  행렬곱의 항등원, 행렬과 역행렬을 곱하면 단위행렬나옴.
    - 역행렬 : 행렬의 나눗셈을 위해 구해서 곱해지는 행렬[정방행렬만 가능]
    - 특이행렬 : 역행렬이 없는 행렬
    - 직교행렬 : 축의 정직교, 각축간의 내적이 0인 행렬
    - 정방행렬이면서 대칭행렬 : 공분산행렬, 상관계수행렬, 거리행렬
    - 공분산 : 두 수 사이의 관계, ((한 수-평균) * (다른 수-평균)) / (n-1)
                                        # 제곱한 효과
    - 상관계수(표준화 -1 ~ 1) : 공분산 / 표준편차의 곱


    import numpy as np
    
    F1 = np.array([[1,2], [3,4]])
    F2 = np.array([[2,2], [2,2]])
    print(F1)
    print(F2)
    print(F1+F2) # 요소끼리
    print(F1*F2)
    print(F1@F2) # 행렬곱도 내적이다. 두 벡터의 사이각을 구해
    # 1,2   2,2      6,6
    # 3,4   2,2     14,14   
    
    # 차원을 축소하여 특징을 추출할 때 한번에 해버리면 데이터 소실이 심하므로, 차원축소를 여러횟수로 나눠서 한다. 이를 딥러닝이라 한다.
    # 예) 100개 -> 2개... (X)      100개 -> 50개 -> 2개 (O)
    
    # 1,2,  2,2,1
    # 3,4   2,2,1      차원확장도 가능
    
    

    [[1 2]
     [3 4]]
    [[2 2]
     [2 2]]
    [[3 4]
     [5 6]]
    [[2 4]
     [6 8]]
    [[ 6  6]
     [14 14]]

     

    # 문제
    # 방정식의 해
    # 2x1 + x2 -2 x3 = -3
    # 3x1 +       x3 = 5
    #  x1 + x2-   x3 = -2
    
    A = np.array([[2,1,-2], [3,0,1], [1,1,-1]])
    print(A)
    b = np.transpose(np.array([[-3,5,-2]])) # 열로 전치
    print(b)
    x = np.linalg.solve(A,b) #A의 역행렬을 구해서 b와 곱해줌
    print(x)

    [[ 2  1 -2]
     [ 3  0  1]
     [ 1  1 -1]]
    [[-3]
     [ 5]
     [-2]]
    [[ 1.]
     [-1.]
     [ 2.]]

     

    linalg = 선형대수학

    np.dot(np.linalg.inv(A),b) # A의 역행렬을 구해서 b와 행렬곱

    array([[ 1.],
           [-1.],
           [ 2.]])

    np.linalg.inv(A)@b # 왜 역행렬을 구해야 하는가? 행렬은 나눗셈이 없기 때문에 역행렬을 곱해서 해결한다

    array([[ 1.],
           [-1.],
           [ 2.]])

    # 검산
    2*1  +  (-1) + -2*2

    -3

     

    a = np.array([0,1,0]) # y축
    b= np.array([1,0,0]) # x축
    res = np.dot(a,b) # 내적 사이각 = 직각
    print(res)

    0

    print(np.linalg.norm(a)) # 벡터의 크기
    print(np.linalg.norm(b))
    print(np.linalg.norm(a) * np.linalg.norm(b))
    rad = res / (np.linalg.norm(a) * np.linalg.norm(b)) # cos(theta) 값을 구함
    print("cos theta", rad)
    print(np.arccos(rad)) #theta 값을 구함
    print(np.degrees(np.arccos(rad))) # 사람이 알아보는 각도로 표현

    1.0
    1.0
    1.0
    cos theta 0.0
    1.5707963267948966
    90.0

    x = np.array([[1,2], [3,4]])
    y = np.linalg.inv(x)
    print(x)
    print(y)
    print(np.dot(x,y))

    [[1 2]
     [3 4]]
    [[-2.   1. ]
     [ 1.5 -0.5]]
    [[1.00000000e+00 1.11022302e-16]
     [0.00000000e+00 1.00000000e+00]]

    # 다음 방정식의 해를 구하고 검산하시오
    x + y + z = 6
    2y + 5z = -4
    2x + 5y -z = 27
    x = np.array([[1,1,1],[0,2,5],[2,5,-1]])
    y = np.transpose(np.array([6,-4,27]))
    print(x); print()
    print(y); print()
    print(np.linalg.solve(x,y))

    [[ 1  1  1]
     [ 0  2  5]
     [ 2  5 -1]]

    [ 6 -4 27]

    [ 5.  3. -2.]

    반응형
Designed by Tistory.