numpy

손호준·2022년 11월 2일
0

numpy는 행렬이나 대규모 다차원 배열을 쉽게 처리할 수 있도록 지원하는 파이썬 라이브러리입니다.

why numpy?

보통의 데이터들은 배열로 구성되어 있습니다. 우리는 차원의 개수에 따라 다음과 같이 부릅니다.

차원 개수명칭
0스칼라
1벡터
2행렬
3+N텐서

numpy를 사용한다는 것은 행렬 구조를 만들어서 빠른 계산을 하겠다는 의미입니다.
1.사용할 데이터를 list형태로 정리
2.데이터를 n차원의 array구조로 생성 (ndarray)
3.numpy에 있는 함수를 사용

#numpy 사용 예시
import numpy as np

a = np.arange(15).reshape(3,-1) #배열 생성# arange: 범위와 간격 설정 가능
print(type(a)) #a의 타입 (<class 'numpy.ndarray'>)
print(a)
print(a.shape)#배열의 모양(각 차원의 배열 크기를 나타내는 정수 튜플)
print(a.ndim) #배열의 차원
print(a.dtype)
print(a.itemsize) #itemsize: 각 바이트 단위의 사이즈
print(a.size) #원소의 개수

b = np.array([20,30,40,50])
c = np.array([1,2,3,4])
print(b-c) # 요소끼리 사칙연산 가능
print(b**2) # 제곱

AA = np.array([[1,1],[0,1]])
BB = np.array([[2,0],[3,4]])
print(AA * BB) #행렬끼리 곱
print(AA @ BB) # 행렬끼리의 매트릭스 곱
print(AA.dot(BB)) # 행렬끼리의 매트릭스 곱

d = np.arange(10)**3 #1부터 10까지 3제곱한 배열 #[  0   1   8  27  64 125 216 343 512 729]
print(d[2]) #인덱싱 #8
print(d[2:5]) #슬라이싱 #[ 8 27 64]
print(d[ : :-1]) # 배열 뒤집은 값 #[729 512 343 216 125  64  27   8   1   0]

#배열 모양 조작 (수정된 배열 반환하지만 원래 배열은 변경하지 않음)
e = np.floor(10*np.random.random((3,4)))
print(e.shape)
print(e.ravel()) # 1차원으로 만듦
print(e.T) # 전치

numpy는 다차원 배열을 연산하는데 있어서 파이썬보다 편하고 빠릅니다. numpy는 C언어의 빠른 속도와 파이썬의 코드 단순성이라는 장점을 모두 갖고 있습니다. 이것은 numpy의 핵심인 ndarray가 C언어 기반이기 때문입니다.

numpy가 파이썬보다 빠른 이유는?(메모리 구조 관점)

C언어 기반인 것이 빠른 이유는 메모리 구조에 있습니다. 기존 파이썬의 list는 2중 포인터 형식으로 아이템을 저장합니다. 첫번째 포인터가 참조하는 곳에는 포인터주소가 있으며, 한번 더 들어가야 아이템이 나타납니다. 포인터주소끼리는 메모리상에서 인접하지만 실제 데이터는 메모리상에 인접한다는 보장이 없습니다. 즉, 아이템들이 서로 연속적이지 않고 여러번의 메모리 할당으로 더 많은 시간이 걸리게 됩니다.

반면 ndarray는 단일 포인터로 버퍼(고정 크기 데이터를 포함하는 연속 메모리 블록인 C나 포트란의 배열) 주소를 가리키고, 버퍼의 배열에 아이템들이 연속적으로 저장됩니다. 파이썬의 list에 비해 접근 단계가 적고 동일한 타입의 데이터들이 연속적으로 저장되기 때문에(C언어의 배열과 동일) 빠른 연속 접근이 가능합니다. 이러한 numpy의 메모리 레이아웃은 캐시 메모리의 공간 지역성(메모리의 주변 데이터를 사용할 확률이 높음)에 적합하여 캐시 적중률(cache hit ratio)을 상승시키고 연산 속도를 증가시킵니다.

ndarray 메모리 레이아웃

ndarray는 메모리 레이아웃을 설정할 수 있습니다. 크게 C언어 스타일의 행우선 방식과, Fortran 언어 스타일의 열우선 방식이 있습니다. 행 우선 방식은 첫 번째 행을 메모리에 넣은 다음 두 번째 행을 메모리에 넣습니다. 열 우선 방식은 첫 번째 열을 메모리에 넣은 다음 두 번째 열을 메모리에 넣습니다. 이렇게 넣는 과정에서 메모리 레이아웃의 구조가 형성됩니다.

import numpy as np
array = np.arange(10) #[0 1 2 3 4 5 6 7 8 9]
print(array)
arrayC = np.reshape(array, (2, -1), order='C') #C언어 스타일
arrayF = np.reshape(array, (2, -1), order='F') #Fortran 스타일
print(arrayC) #[[0 1 2 3 4 ] [5 6 7 8 9]]
print(arrayF) #[[0 2 4 6 8] [1 3 5 7 9]]

numpy는 코드의 벡터화로 for문과 같은 명시적 루핑이 없어 가볍고, 더간결하며 읽기 쉽습니다. 간결한 코드는 버그 발생 확률을 감소시킵니다. 또한 특정 조건(차원의 크기가 1일때, 차원의 짝이 맞을 때)을 만족했을때 모양이 다른 배열들 간의 연산이 가능해지도록 배열을 자동적으로 변환해주는 브로드캐스팅이 가능합니다. 이러한 요소들은 numpy의 생산성을 향상시켜줍니다.

pandas

pandas는 고수준의 자료구조와 빠르고 쉬운 데이터 처리를 위한 numpy 기반의 파이썬 라이브러리입니다. numpy기반이기 때문에 numpy의 기능을 모두 포함하지만 느리다는 단점이 있고, 최대 2차원의 데이터만 담을 수 있습니다. pandas는 행과열을 조작하거나 결측치를 처리하거나 데이터베이스와 통합하는데 유용합니다. 판다스의 자료구조는 차원의 개수에 따라 시리즈(1차원), 데이터 프레임(2차원), 패널(3차원) 3가지로 분류됩니다.

1.시리즈(series)

시리즈는 1차원 배열의 값에 대응되는 인덱스를 부여할 수 있는 구조입니다. 기존 파이썬의 리스트와 달리 인덱스에 이름을 부여할 수 있습니다.

import pandas as pd

#시리즈 생성
dict = {'a':1, 'b':2, 'c':3, 'd':4}
u =pd.Series(dict)
print(u)
"""
a    1
b    2
c    3
d    4
dtype: int64
"""

data = [1,3,5,7,9]
s = pd.Series(data)
print(s)
"""
0    1
1    3
2    5
3    7
4    9
dtype: int64
"""

2.데이터 프레임(data frame)

데이터 프레임은 2차원 리스트를 매개변수로 전달하여 행방향과 열방향 인덱스가 존재합니다. 시리즈처럼 값과 인덱스를 갖고, 추가로 열까지 갖습니다. 리스트, 시리즈, 딕셔너리, ndarray나 또 다른 데이터 프레임으로부터도 생성이 가능합니다.

import numpy as np
import pandas as pd

#data frame 생성
name_list = ['h','j','son']
df = pd.DataFrame(name_list)
print(df)
"""
0    h
1    j
2    son
"""
df2 = pd.DataFrame({'A': 1.,
                    'B': pd.Timestamp('20190102'),
                    'C': pd.Series(1, index=list(range(4)), dtype='float32'),
                    'D': np.array([3] * 4, dtype='int32'),
                    'E': pd.Categorical(["test", "train", "test", "train"]),
                    'F': 'foo'})
print(df2)
"""
A          B        C   D      E    F
0  1.0 2019-01-02  1.0  3   test  foo
1  1.0 2019-01-02  1.0  3  train  foo
2  1.0 2019-01-02  1.0  3   test  foo
3  1.0 2019-01-02  1.0  3  train  foo
"""

3.패널(panel)

패널은 3차원 데이터이고, 데이터프레임 모음이라고 할 수 있습니다.
간단히 생각하면 시리즈가 모여 데이터프레임이 되고, 데이터프레임이 모여 패널이 됩니다.

numpy와 pandas의 차이점

Numpy는 배열이며 머신러닝/딥러닝 알고리즘에서 연산의 강점을 갖습니다.
Pandas는 Data_Table 구조이며 데이터 관리에서 강점을 갖습니다.

profile
Rustacean🦀/Data engineer💻

0개의 댓글