Ch4. NumPy 기본 : 배열과 벡터 연산

NumPy = Numerical Python

  • 효율적인 다차원 배열인 ndarray는 빠른 배열 계산과 유연한 브로드캐스팅 기능 제공

  • 반복문 작성 없이 전체 데이터 배열을 빠르게 계산할 수 있는 표준 수학 함수

  • 배열 데이터를 디스크에 쓰거나 읽을 수 있는 도구와 메모리에 적재된 파일을 다루는 도구

  • 선형대수, 난수 생성기, 푸리에 변환 기능

  • C, C++, 포트란으로 작성한 코드를 연결할 수 있는 C API

ndarry : 같은 종류의 데이터를 담을 수 있는 포괄적인 다차원 배열. 모든 원소는 같은 자료형이어야 한다. 배열을 생성하는 가장 쉬운 방법은 array 함수를 이용하여, 순차적인 객체 (다른 배열도 포함) 를 넘겨받고, 넘겨받은 데이터가 들어있는 새로운 Numpy 배열을 생성. 리스트는 변환하기 좋은 예. 데이터 복사가 되지 않는다. 복사 하려면 .copy 함수 사용.

배열 위주의 프로그래밍과 생각하는 방법에 능숙해지는것이 데이터 사이언티스트 고수가 되는 지름길이다.

배열 zeros, ones, empty, arrange 를 사용해서 함수의 배열을 만들 수 있다. arrange는 파이썬 range 함수의 배열 버전

np.empty((2,3))
>>array([[0., 0., 0.],
         [0., 0., 0.]])
         
np.empty((2,3,2))
>>array([[[0., 0.],
          [0., 0.],
          [0., 0.]],

         [[0., 0.],
          [0., 0.],
          [0., 0.]]])
          
 np.array(15)
 >> array([0,1,2,3,4,5,6,7,8,9,10,11,12,13,14])

벡터화 : 배열의 중요한 특징으로 for 문을 작성하지 않고 데이터 일괄 처리 가능 같은 크기의 배열간의 산술 연산은 배열의 각 원소 단위로 적용. 비교 연산은 불리언 배열을 반환. 브로드캐스팅 : 크기가 다른 배열간의 연산

배열 형태 변환 실수 > 정수로 바꾸게 되면 소수점 아래 리는 버려진다. 숫자 형식의 문자열이 있다면 astype 사용하여 숫자로 변환 가능 (NumPy에서 문자열 데이터는 고정 크기를 가지며, 별다른 경고 없이 임의로 자를 수 있으니 numpy.string_ 형을 사용할 때 주의해야한다. pandas 쓰는 것 권장) 형 변환 실패하면 ValueError 예외 발생.

arr=np.array([1,2,3,4,5])
arr.dtype
>> dtype('int65')

float_arr=arr.astype(np.float64)
float_arr.dtype
>> dtype('float64')

슬라이싱을 한 후 원소를 바꾸면 원래 배열의 원소도 바뀌어진다.

배열 전와 축 바꾸기 i, j , k 배열 위치. 행렬의 내적은 np.dot( , ) 이용

arr=np.arange(24).reshape((2,3,4))
>>
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]]])
        
#i는 쉽게 말하면 j,k 배열의 덩어리. j는 가로축, k는 세로축  

transpose( ) , swapaxes()

#0,1,2 는 i,j,k 를 의미한다. 0=i, 1=j, 2=k
#3차원 행렬 뿐 아니라 4차원등 고차원 행렬도 가능하다 

arr.transpose(2,0,1) 
>>
array([[[ 0,  4,  8],
        [12, 16, 20]],

       [[ 1,  5,  9],
        [13, 17, 21]],

       [[ 2,  6, 10],
        [14, 18, 22]],

       [[ 3,  7, 11],
        [15, 19, 23]]])
        
#transpose(2,0,1)는 i,j,k 배열을  k,i,j 배열로 바꾼다는 
#(2,3,4)배열이 (4,2,3) 배열로 뀌어졌다.

swapaxes()는 transpose와 다르게 바꾸는 축만 쓴다. 단, 축 2개만 바꿀 수 있다. transpose에서 2개만 바꾸는것과 동일한 결과가 온.

유니버설 함수 : ndarray 안에 있는 데이터 원소별로 연산을 수행. 하나 이상의 스칼라값을 받아서 하나 이상의 스칼라 결과값을 반환하는 간단한 함수를 고속으로 수행할 수 있는 벡터화된 함수. 유니버설 함수는 선택적으로 out 인자를 취해 계산 결과를 따로 저장할 수 있다. 단항 함수 : 한개의 인자를 취하는 경우 ex) np.sqrt(arr) 처럼 배열 전체를 취한다 이항 함수 : 2개의 인자를 취해서 단일 배열을 반환. ex) add, maximum, mdof x = np.random.randn(8) y = np.random.randn(8) np.maximum(x,y) x,y 통틀어서 가장 높은 원소 8개를 반환한다. 만일 x 배열이 6, y 배열이 4개처럼 배열수가 다르면 error 나옴.

NumPy 배열을 사용하면 반복문을 작성하지 않고, 간결한 배열 연산을 사용해 더 빠른 속도로 많은 종류의 데이터 처리 작업을 할 수 있다!

where 데이터 분석에서 다른 배열에 기반한 새로운 배열 생성. ex) 행렬이 있고 양수는 모두 2, 음수는 모두 -2로 바꿀 때 arr=np.random.randn(4,4) np.where(arr>0, 2, -2)

수학/통계 메서드는 axis 를 사용해서 특정 행에 대한 통계를 낼 수 있다. 최대,최소,평균 말고도 누적 합/곱을 구할수도 있다. arr.mean() #arr 전체의 평균값 arr.mean(axiz=1) # 1행의 평균값

불리언 배열을 위한 메서드 불리언값을 1(True) 또는 0(False)로 강제할 수 있다. any 메서드는 하나 이상의 값이 True인지 검사, all 메서드는 모든 원소가 True인지 검사.

arr=np.random.randn(100)
(arr>0).sum() #양수인 원소의 개수
>>42 

bools=np.array([False, True, False, False])
bools.any()
>>True
bools.all()
>>False

정렬 sort() : 작은 것 부터 큰 수로 정렬이 된다. unique() : 중복된 원소를 제거하고 남은 원소를 정렬된 형태로 반환한다

arr=np.random.randn(5,3) arr.sort()

names=np.array(['bob','will','chloe','chloe','bob','joe',]) np.unique(names)
np.unique(names)
#sorted(set(naems) 로도 표현 할 수 있다

선형대수 행렬 곱셈

x=np.array([1,2,3],[4,5,6])
y=np.array([6,-23], [-1,7], [8,9])

x.dot(y)
>>array([28,64],[67,181])

np.dot(x,y)
>>array([28,64],[67,181])
#x.dot(y) 와 np.dot(x,y) 는 결과값이 같다 

numpy.linalg는 행렬의 분할과 역행렬, 행렬식과 같은 것들을 포함하고 있다.

계단 오느내리기 예제

시뮬레이션 : 100번. (nsteps=100) 올라가거나 내려가거나 두가지 경우만 존재. ( steps = np.where(draws >0, 1, -1) 위치 : 누적으로 계산 (walk=steps.cumsum() ) 위치의 최소값/최댓값 : walk.min() / walk.max() 처음 위치가 -10 혹은 +10이 되었을 때의 step 횟수 : np.abs(walk) >=10.argmax()

5000번 시뮬레이션해서, 누적합이 30 또는 -30 되는 경우의 수 계산하기. 여러번의 시뮬레이션을 한번에 처리하기 위해서는 2차원 배열로 누적합을 구하면 된다.

5000번 중 3389번이 누적합이 30 또는 -30이 되었다.

Last updated

Was this helpful?