Life is short. You need Python.
관례상 Scipy와 PyData를 사용하는 대부분의 사용자는 Numpy를 별칭(alias)인 np를 사용해 import 한다.
import numpy as np
import는 파이썬에서 라이브러리를 읽기 위해 사용하는 명령어이다.
Numpy는 외부라이브러리로 본래 파이썬을 다운받을 때 존재하지 않는 라이브러리이다. 그래서 이 모듈을 가져오기 위해서 import를 사용한다.
## ndarray 다차원 배열 객체
ndarray는 같은 종류의 데이터를 담을 수 있는 포괄적인 다차원 배열이다. ndarray의 모든 원소는 같은 자료형이어야만 한다.
shape : 모든 배열은 각 차원의 크기를 알려주는 튜플, 차원의 구조를 볼 때 사용 (행, 렬)로 표시됨.
dtype : 배열에 저장된 자료를 알려주는 객체
import numpy as np
a = np.array([1, 2, 3]) # rank가 1인 배열 생성
a.dtype
dtype('int64')
a.shape
(3,)
b = np.array([[1,2,3],[4,5,6]])
type(b)
numpy.ndarray
b.shape
(2, 3)
## 1. 1 배열 생성 함수 ###
np.array()
다차원 배열 생성시 배열의 길이가 동일해야 함.
다차원 배열은 일종의 매트릭스와도 비슷하다.
순서가 있는 배열은 벡터(;크기와 방향을 가진 양; 수와 순서쌍으로 구성)와도 비슷해보임
np.zeros , np.ones
각각 0과 1이 들어있는 배열을 생성한다.
다차원 배열을 생성하려면 (행,열)로된 튜플을 넘기면 된다.
np.zeros((3,4))
array([[0., 0., 0., 0.],
[0., 0., 0., 0.],
[0., 0., 0., 0.]])
np.empty
np.arange(n)
1차원 배열
x = np.arange(10)
x
array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
x[:5]
array([0, 1, 2, 3, 4])
x[5:]
array([5, 6, 7, 8, 9])
x[4:7]
array([4, 5, 6])
x[::2]
array([0, 2, 4, 6, 8])
x[1::2]
array([1, 3, 5, 7, 9])
x[::-1]
array([9, 8, 7, 6, 5, 4, 3, 2, 1, 0])
x[5::-2]
array([5, 3, 1])
a=np.arange(13)
a
array([ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12])
답변 ↓
print(a[-3::-3])
[10 7 4 1]
배열 인덱싱은 개별 배열 요소값을 가져오고 설정할 수 있습니다.
square bracket 안에 원하는 인덱스 값을 지정할 수 있습니다.
배열의 끝에서 부터 인덱싱할려면 음수 인덱스를 사용하면 됩니다.
x1 = np.random.randint(10, size=((3,4)))
x1
array([[9, 3, 4, 9],
[6, 6, 7, 8],
[6, 2, 1, 5]])
x1[0,0]
9
x1[0,0] =12
x1
array([[12, 3, 4, 9],
[ 6, 6, 7, 8],
[ 6, 2, 1, 5]])
다차원 배열에서는 콤마로 구분된 인덱스 튜플을 이용해 배열 항목에 접근할 수 있습니다.
인덱스 표기법을 사용해 값을 수정할 수도 있습니다.
x2 = np.random.randint(10,size=(3,4))
x2
array([[6, 4, 4, 3],
[0, 0, 8, 8],
[1, 4, 0, 2]])
x2[:2,:3]
array([[6, 4, 4],
[0, 0, 8]])
grid = np.arange(1,10).reshape((3,3))
grid
array([[1, 2, 3],
[4, 5, 6],
[7, 8, 9]])
grid.reshape((1,9))
array([[1, 2, 3, 4, 5, 6, 7, 8, 9]])
grid.reshape((3,2))
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
<ipython-input-24-df39b94ccfc8> in <module>
----> 1 grid.reshape((3,2))
ValueError: cannot reshape array of size 9 into shape (3,2)
## 배열 연결 및 분할
### 배열 연결
x = np.array([1,2,3])
y = np.array([3,2,1])
np.concatenate([x,y])
array([1, 2, 3, 3, 2, 1])
한번에 두 개 이상의 배열을 연결할 수도 있다.
z=[99,99,99]
print(np.concatenate([x,y,z]))
[ 1 2 3 3 2 1 99 99 99]
### np.concatenate는 2차원 배열에서도 사용할 수 있다.
grid = np.array([[1, 2, 3],[4, 5, 6]])
np.concatenate([grid, grid])
array([[1, 2, 3],
[4, 5, 6],
[1, 2, 3],
[4, 5, 6]])
np.concatenate([grid, grid], axis=1)
array([[1, 2, 3, 1, 2, 3],
[4, 5, 6, 4, 5, 6]])
파이썬의 기본 구현에서 몇 가지 연산은 느리게 수행됩니다. 이는 부분적으로 파이썬이 동적인 인터프리터 언어이기 때문입니다.
파이썬은 수많은 작은 연산이 반복되는 상황에서 확연히 느립니다.
cf) 인터프리터 언어란?
cf) 컴파일 언어란?
C, C++, JAVA, C#등
NumPy는 정적 타입 체계를 가진 컴파일된 루틴에 편리한 인터페이스를 제공하는데 이를 벡터화 연산이라고 한다.
NumPy에서 벡터화 연산은 NumPy 배열의 값에 반복된 연산을 빠르게 수행하는 것을 주목적으로 하는 ufuncs를 통해 구현된다.
np.arange(5)/np.arange(1,6)
array([0. , 0.5 , 0.66666667, 0.75 , 0.8 ])
#### 배열 산술 연산- NumPy ufuncs는 파이썬의 기본 산술 연산자를 사용한다.
x= np.arange(4)
print("x=",x)
print("x+5=",x+5)
print("x-5=",x-5)
print("x*2=",x*2)
print("x/2=",x/2)
print("x//2=",x//2) # 바닥 나눗셈( 나머지는 버림)
x= [0 1 2 3]
x+5= [5 6 7 8]
x-5= [-5 -4 -3 -2]
x*2= [0 2 4 6]
x/2= [0. 0.5 1. 1.5]
x//2= [0 0 1 1]
np.add(x,5)
array([5, 6, 7, 8])
복소수 데이터도 처리할 수 있으며, 이경우에는 절댓값은 크기를 반환한다.
x=np.array([-2,-1,0,1,2])
np.abs(x)
array([2, 1, 0, 1, 2])
np.absolute(x)
array([2, 1, 0, 1, 2])
x=np.array([3-4j, 4-3j, 2+0j, 0+1j])
np.abs(x)
array([5., 5., 2., 1.])
theta = np.linspace( 0, np.pi, 3)
print("theta = ", theta)
print(" sin(theta)= ", np.sin(theta))
print(" cos(theta)= ", np.cos(theta))
print(" tan(theta)= ", np.tan(theta))
theta = [0. 1.57079633 3.14159265]
sin(theta)= [0.0000000e+00 1.0000000e+00 1.2246468e-16]
cos(theta)= [ 1.000000e+00 6.123234e-17 -1.000000e+00]
tan(theta)= [ 0.00000000e+00 1.63312394e+16 -1.22464680e-16]
x=[1,2,3]
print("x = ",x)
print("e^x = ", np.exp(x) )
print("2^x =", np.exp2(x))
print("3^x =", np.power(3, x))
x = [1, 2, 3]
e^x = [ 2.71828183 7.3890561 20.08553692]
2^x = [2. 4. 8.]
3^x = [ 3 9 27]
x = [1, 2, 4, 10]
print("x =", x)
print("ln(x) =", np.log(x))
print("log2(x) =", np.log2(x))
print("log10(x) =", np.log10(x))
x = [1, 2, 4, 10]
ln(x) = [0. 0.69314718 1.38629436 2.30258509]
log2(x) = [0. 1. 2. 3.32192809]
log10(x) = [0. 0.30103 0.60205999 1. ]
대규모 연산인 경우, 연산 결과를 저장할 배열을 지정하는 것이 유용할 대가 있다. 임시배열을 생성하지 않고 지정한 배열을 이용해 원하는 메모리 위치에 직접 연산 결과를 쓸 수 있다.
모든 ufuncs 에서 함수의 out 인수를 사용해 출력을 지정할 수 있다.
x = np.arange(5)
y = np.empty(5)
np.multiply(x, 10, out=y)
print(y)
[ 0. 10. 20. 30. 40.]
y = np.zeros(10)
np.multiply(2, x, out=y[::2])
print(y)
[0. 0. 2. 0. 4. 0. 6. 0. 8. 0.]
배열을 특정 연산으로 축소하고자 한다면 reduce 메서드를 사용하면 됩니다.
reduce 메서드는 결과가 하나만 남을 때까지 해당 연산을 배열 요소에 반복해서 적용합니다.
x = np.arange(1, 6)
np.add.reduce(x)
15
np.multiply.reduce(x)
120
x = np.arange(1, 6)
np.add.accumulate(x)
array([ 1, 3, 6, 10, 15])
np.multiply.accumulate(x)
array([ 1, 2, 6, 24, 120])
느린 파이썬 루프를 제거하기 위해 연산을 벡터화 하는 NumPy의 유니버설 함수 사용법을 했었다.
벡터화 연산의 또 다른 방법은 NumPy의 브로드 캐스팅 기능을 사용하는 것이다.
a = np.array([1,2,3])
b=np.array([1,2])
a+b
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
<ipython-input-45-cc3620bbd4ac> in <module>
2 b=np.array([1,2])
3
----> 4 a+b
ValueError: operands could not be broadcast together with shapes (3,) (2,)
브로드캐스팅은 어떤 조건만 만족한다면 모양이 다른 배열끼리의 연산도 가능하게 해주며 모양이 부족한 부분은 확장하여 연산을 수행할 수 있도록 한다.
확장 또는 전파한다는 의미로 Broadcasting을 설명하는 가장 간단한 예는 배열과 스칼라 값을 계산하는 것이다.
위의 그림에서는 첫 번째 그림에 해당하는 것으로 0, 1, 2라는 NumPy로 생성한 배열에 스칼라 5를 합한 결과가 5, 6, 7이라는 것을 알 수 있다. 일반적인 파이썬 리스트를 사용하면 for문을 이용해야 같은 결과를 얻을 수 있지만, NumPy에서는 브로드캐스팅의 개념 덕분에 5가 0이외에 1과 2의 원소 부분에도 전파(broadcast)되어 계산되어 간단하게 합 연산을 수행하는 것만으로 같은 결과를 얻을 수 있었다.
두 번째 그림은 배열 간의 계산으로 배열의 차원이 확대된 케이스이다. 두 번째 그림은 3x3 배열에 1x3 배열을 합 연산한 경우이다. 각 행에 동일한 계산을 전파한 것을 볼 수 있다.
세번째 그림은 브로드캐스팅의 확장성 측면을 극명하게 보여주는 케이스이다. 3x1 배열과 1x3 배열의 합을 했는데 두 번째에서는 한쪽의 더 낮은 차원의 배열에서만 아래(0번 축) 방향으로 broadcast한 것에 반해 양 쪽 배열에서 broadcast한 것을 확인할 수 있다.
브로드캐스팅이 일어날 수 있는 조건은 다음과 같다.
• 규칙 1 : 두 배열의 차원 수가 다른 경우 치수가 더 작은 배열의 모양에 선행 (왼쪽)면이있는 모양이 채워집니다.
• 규칙 2 : 두 배열의 모양이 임의의 차원에서 일치하지 않으면 해당 차원의 모양이 1 인 배열이 다른 모양과 일치하도록 늘어납니다.
• 규칙 3 : 크기가 어느 정도라도 크기가 일치하지 않고 둘 다 1과 같으면 오류가 발생합니다.
a = np.array([1,2,3])
b=np.array([1,2])
a+b
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
<ipython-input-46-cc3620bbd4ac> in <module>
2 b=np.array([1,2])
3
----> 4 a+b
ValueError: operands could not be broadcast together with shapes (3,) (2,)
b.shape=(2,1)
a+b
array([[2, 3, 4],
[3, 4, 5]])
np.ones((3,1))
array([[1.],
[1.],
[1.]])
np.arange(3)
array([0, 1, 2])
np.ones((3,3))+np.arange(3)
array([[1., 2., 3.],
[1., 2., 3.],
[1., 2., 3.]])
rng = np.random.RandomState(0)
x = rng.randint(10, size=(3, 4))
x
array([[5, 0, 3, 3],
[7, 9, 3, 5],
[2, 4, 7, 6]])
x < 6
array([[ True, True, True, True],
[False, False, True, True],
[ True, True, False, False]])
# 8보다 큰 값이 하나라도 있는가
np.any(x > 8)
True
#0보다 작은 값이 하나라도 있는가?
np.any(x < 0)
False
#모든 값이 10보다 작은가
np.all(x<10)
True
#모든 값이 6과 같은가?
np.all(x==6)
False
# 각 행의 모든 값이 8보다 작은가
np.all(x < 8, axis=1)
array([ True, False, True])
axis =0 세로 열,
axis =1 가로 행
부울 배열을 마스크로 사용해 데이터 자체의 특정 부분 집합을 선택할 수 있습니다.
부울 배열을 인덱스로 사용해서 조건에 맞는 값을 선택할 수 있습니다. 이를 마스킹 연산이라고 합니다.
x
array([[5, 0, 3, 3],
[7, 9, 3, 5],
[2, 4, 7, 6]])
x < 5
array([[False, True, True, True],
[False, False, True, False],
[ True, True, False, False]])
x[x < 5]
array([0, 3, 3, 3, 2, 4])
import numpy as np
rand = np.random.RandomState(42)
x = rand.randint(100, size=10)
print(x)
[51 92 14 71 60 20 82 86 74 74]
[x[3], x[7], x[2]]
[71, 86, 14]
세 개의 다른 요소에 접근하고자 할 때, 다음과 같이 할 수 있습니다.
ind = [3, 7, 4]
x[ind]
array([71, 86, 60])
인덱스의 단일 리스트나 배열을 전달해서 팬시인덱싱을 할 수도 있습니다.
X = np.arange(12)
X
array([ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11])
i = np.array([2,4,6,8,10])
X[i]=0
print(X)
[ 0 1 0 3 0 5 0 7 0 9 0 11]
테이블을 수정하고 조작하는 다양한 기능 제공
SQL, 엑셀파일, CSV 파일과 데이터 베이스의 데이터를 읽어들임
import pandas as pd
obj = pd.Series([4,1,2,3])
obj
0 4
1 1
2 2
3 3
dtype: int64
obj.values
array([4, 1, 2, 3])
obj.index
RangeIndex(start=0, stop=4, step=1)
obj.dtypes
dtype('int64')
obj2=pd.Series([20,21,25,4],index=['a','b','c','d'])
obj2
a 20
b 21
c 25
d 4
dtype: int64
data = {'Hong':27,'Yang':25,'Kim':27}
obj3=pd.Series(data)
obj3
Hong 27
Yang 25
Kim 27
dtype: int64
자료들의 이름을 지정해 줄수도 있다.
obj3.name = 'Lab'
obj3
Hong 27
Yang 25
Kim 27
Name: Lab, dtype: int64
obj3.index.name = "NAMES"
obj3
NAMES
Hong 27
Yang 25
Kim 27
Name: Lab, dtype: int64
obj3[:'Yang']
NAMES
Hong 27
Yang 25
Name: Lab, dtype: int64
obj3[0:3]
NAMES
Hong 27
Yang 25
Kim 27
Name: Lab, dtype: int64
population_dict = {'California': 38332521,'Texas': 26448193,'New York': 19651127,'Florida': 19552860,'Illinois': 12882135}
population = pd.Series(population_dict)
population
California 38332521
Texas 26448193
New York 19651127
Florida 19552860
Illinois 12882135
dtype: int64
pd.Series(population_dict,index=['Texas','Florida'])
Texas 26448193
Florida 19552860
dtype: int64
population_dict = {'California': 38332521,'Texas': 26448193,'New York': 19651127,'Florida': 19552860,'Illinois': 12882135}
area_dict = {'California': 423967, 'Texas': 695662, 'New York': 141297,'Florida': 170312, 'Illinois': 149995}
area =pd.Series(area_dict)
area
California 423967
Texas 695662
New York 141297
Florida 170312
Illinois 149995
dtype: int64
states = pd.DataFrame({'population': population,'area': area})
states
population | area | |
---|---|---|
California | 38332521 | 423967 |
Texas | 26448193 | 695662 |
New York | 19651127 | 141297 |
Florida | 19552860 | 170312 |
Illinois | 12882135 | 149995 |
states.index
Index(['California', 'Texas', 'New York', 'Florida', 'Illinois'], dtype='object')
states.columns
Index(['population', 'area'], dtype='object')
states['area']
California 423967
Texas 695662
New York 141297
Florida 170312
Illinois 149995
Name: area, dtype: int64
pd.DataFrame(population,columns=['area'])
area | |
---|---|
California | 38332521 |
Texas | 26448193 |
New York | 19651127 |
Florida | 19552860 |
Illinois | 12882135 |
data={"name":["용기","재은","태진","재열"],"Year":[1993,1995,1992,1993],"number":[1,2,3,4]}
df=pd.DataFrame(data)
df
name | Year | number | |
---|---|---|---|
0 | 용기 | 1993 | 1 |
1 | 재은 | 1995 | 2 |
2 | 태진 | 1992 | 3 |
3 | 재열 | 1993 | 4 |
df.index.name ="Num"
df.columns.name = "Info"
df
Info | name | Year | number |
---|---|---|---|
Num | |||
0 | 용기 | 1993 | 1 |
1 | 재은 | 1995 | 2 |
2 | 태진 | 1992 | 3 |
3 | 재열 | 1993 | 4 |
(NaN은 Not a Number를 의미하며, 해당하는 값이 없다는 뜻입니다.)
df2=pd.DataFrame(data,columns=["Year","name","number","project"])
df2
Year | name | number | project | |
---|---|---|---|---|
0 | 1993 | 용기 | 1 | NaN |
1 | 1995 | 재은 | 2 | NaN |
2 | 1992 | 태진 | 3 | NaN |
3 | 1993 | 재열 | 4 | NaN |
DataFrame 변수[“칼럼명”]
df[“컬럼이름”]
df.컬럼이름
DataFrame에서 하나의 열을 가져온 결과는 Series의 모양을 하고 있다
df2["name"]
0 용기
1 재은
2 태진
3 재열
Name: name, dtype: object
df2.name
0 용기
1 재은
2 태진
3 재열
Name: name, dtype: object
df2[["Year","name"]]
Year | name | |
---|---|---|
0 | 1993 | 용기 |
1 | 1995 | 재은 |
2 | 1992 | 태진 |
3 | 1993 | 재열 |
df2
Year | name | number | project | |
---|---|---|---|---|
0 | 1993 | 용기 | 1 | NaN |
1 | 1995 | 재은 | 2 | NaN |
2 | 1992 | 태진 | 3 | NaN |
3 | 1993 | 재열 | 4 | NaN |
df2["project"]="Ai"
df2
Year | name | number | project | |
---|---|---|---|---|
0 | 1993 | 용기 | 1 | Ai |
1 | 1995 | 재은 | 2 | Ai |
2 | 1992 | 태진 | 3 | Ai |
3 | 1993 | 재열 | 4 | Ai |
df2["project"]=["Ai","Ai","Ai","PET"]
df2
Year | name | number | project | |
---|---|---|---|---|
0 | 1993 | 용기 | 1 | Ai |
1 | 1995 | 재은 | 2 | Ai |
2 | 1992 | 태진 | 3 | Ai |
3 | 1993 | 재열 | 4 | PET |
df2["grade"]=["4학년","대학원생","대학원생","대학원생"]
df2
Year | name | number | project | grade | |
---|---|---|---|---|---|
0 | 1993 | 용기 | 1 | Ai | 4학년 |
1 | 1995 | 재은 | 2 | Ai | 대학원생 |
2 | 1992 | 태진 | 3 | Ai | 대학원생 |
3 | 1993 | 재열 | 4 | PET | 대학원생 |
add=pd.Series([1,2,3,4],index=[3,2,1,0])
df2["등수"]=add
df2
Year | name | number | project | grade | 등수 | |
---|---|---|---|---|---|---|
0 | 1993 | 용기 | 1 | Ai | 4학년 | 4 |
1 | 1995 | 재은 | 2 | Ai | 대학원생 | 3 |
2 | 1992 | 태진 | 3 | Ai | 대학원생 | 2 |
3 | 1993 | 재열 | 4 | PET | 대학원생 | 1 |
df2.T
0 | 1 | 2 | 3 | |
---|---|---|---|---|
Year | 1993 | 1995 | 1992 | 1993 |
name | 용기 | 재은 | 태진 | 재열 |
number | 1 | 2 | 3 | 4 |
project | Ai | Ai | Ai | PET |
grade | 4학년 | 대학원생 | 대학원생 | 대학원생 |
등수 | 4 | 3 | 2 | 1 |
score ={"수학":[30,90],"영어":[60,100]}
df3= pd.DataFrame(score,index=["철수","영희"])
df3
수학 | 영어 | |
---|---|---|
철수 | 30 | 60 |
영희 | 90 | 100 |
df3.T
철수 | 영희 | |
---|---|---|
수학 | 30 | 90 |
영어 | 60 | 100 |