[Pandas 기초] 시리즈와 데이터프레임의 산술연산
업데이트:
1. 시리즈의 산술연산
1-1. 시리즈 vs 숫자
student1 = pd.Series({'국어':100,'영어':80,'수학':90})
student1
[Output]
국어 100
영어 80
수학 90
dtype: int64
print(student1/200)
print('\n')
print(type(student1/200))
[Output]
국어 0.50
영어 0.40
수학 0.45
dtype: float64
<class 'pandas.core.series.Series'>
1-2. 시리즈 vs 시리즈
시리즈와 시리즈 간의 연산은 같은 인덱스를 가진 원소끼리 연산하여 새 시리즈를 반환해준다.
같은 인덱스를 가지지만 순서가 다른 두 시리즈를 생성한다.
student1 = pd.Series({'국어':100, '영어':80,'수학':90})
student2 = pd.Series({'수학':80, '국어':90, '영어':80})
print(student1)
print('\n')
print(student2)
[Output]
국어 100
영어 80
수학 90
dtype: int64
수학 80
국어 90
영어 80
dtype: int64
사칙연산을 해보자
add_data = student1 + student2 # 덧셈
sub_data = student1 - student2 # 뺄셈
mul_data = student1 * student2 # 곱셈
div_data = student1 / student2 # 나눗셉
# 결과를 데이터 프레임으로 합치기 (시리즈 -> 데이터프레임)
result = pd.DataFrame([add_data,sub_data,mul_data,div_data], index = ['덧셈','뺄셈','곱셈','나눗셈'])
print(result)
[Output]
국어 수학 영어
덧셈 190.000000 170.000 160.0
뺄셈 10.000000 10.000 0.0
곱셈 9000.000000 7200.000 6400.0
나눗셈 1.111111 1.125 1.0
참고로 시리즈를 데이터프레임으로 변환할때,
시리즈는 []
안으로 합치면 각 인덱스는 열이름이된다.
1-3. NaN값이 있는 시리즈 연산
이번엔 한 시리즈에 인덱스가 하나가 없고, 한 시리즈에는 Nan이 있는 경우의 연산을 해보자
import pandas as pd
import numpy as np
student1 = pd.Series({'국어':np.nan, '영어':80,'수학':90})
student2 = pd.Series({'수학':80, '국어':90})
print(student1)
print('\n')
print(student2)
print(student1 + student2)
[Output]
국어 NaN
수학 170.0
영어 NaN
이처럼 NaN과의 연산 결과는 NaN이고, 인덱스가 없는 경우도 NaN으로 반환해준다.
1-4. 연산메소드(add()
, sub()
, mul()
, div()
)와 fill_value()
앞에서는 사칙연산을 + - * / 로 직접 해주었으나 연산함수도 존재한다.
그리고 앞에서 연산결과가 NaN이 되는 두가지 경우에 대해 fill_value
옵션으로 값을 대체해 줄 수 있다.
import pandas as pd
import numpy as np
student1 = pd.Series({'국어':np.nan, '영어':80,'수학':90})
student2 = pd.Series({'수학':80, '국어':90})
print(student1)
print('\n')
print(student2)
[Output]
국어 NaN
영어 80.0
수학 90.0
dtype: float64
수학 80
국어 90
dtype: int64
사칙연산 대신 연산메소드를 사용랬고, NaN을 0으로 대체주라는 명령을 했다.
add_data = student1.add(student2, fill_value=0)
sub_data = student1.sub(student2, fill_value=0)
mul_data = student1.mul(student2, fill_value=0)
div_data = student1.div(student2, fill_value=0)
result = pd.DataFrame([add_data,sub_data,mul_data,div_data], index = ['덧셈','뺄셈','곱셈','나눗셈'])
print(result)
[Output]
국어 수학 영어
덧셈 90.0 170.000 80.000000
뺄셈 -90.0 10.000 80.000000
곱셈 0.0 7200.000 0.000000
나눗셈 0.0 1.125 inf
여기스 inf
는 무한대(infinite)라는 의미로, ‘영어’인덱스를 연산할때 NaN을 0으로 대체해 주라고 했으므로 80나누기0은 무한대이기 때문이다. (80나누기0인 이유는 연산메소드를 student1에 2를 걸어줬기 때문이다.)
2. 데이터프레임의 산술연산
2-1. 데이터프레임 vs 숫자
데이터프레임은 결국 시리즈의 확장이기 때문에 시리즈의 연산과 별다른 차이는 없다.
이번에는 seaborn 라이브러리에서 제공하는 타이타닉 데이터를 불러와보자
import pandas as pd
import seaborn as sns
titanic = sns.load_dataset('titanic')
titanic.head()
survived | pclass | sex | age | sibsp | parch | fare | embarked | class | who | adult_male | deck | embark_town | alive | alone | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0 | 0 | 3 | male | 22.0 | 1 | 0 | 7.2500 | S | Third | man | True | NaN | Southampton | no | False |
1 | 1 | 1 | female | 38.0 | 1 | 0 | 71.2833 | C | First | woman | False | C | Cherbourg | yes | False |
2 | 1 | 3 | female | 26.0 | 0 | 0 | 7.9250 | S | Third | woman | False | NaN | Southampton | yes | True |
3 | 1 | 1 | female | 35.0 | 1 | 0 | 53.1000 | S | First | woman | False | C | Southampton | yes | False |
4 | 0 | 3 | male | 35.0 | 0 | 0 | 8.0500 | S | Third | man | True | NaN | Southampton | no | True |
앞에서 배운 데이터프레임의 인덱싱을 이용해서 age, fare열만 가져오자.
df = titanic.loc[:, ['age','fare']]
df.head()
age | fare | |
---|---|---|
0 | 22.0 | 7.2500 |
1 | 38.0 | 71.2833 |
2 | 26.0 | 7.9250 |
3 | 35.0 | 53.1000 |
4 | 35.0 | 8.0500 |
여기에 10을 더해보자
addition = df + 10
addition.head()
age | fare | |
---|---|---|
0 | 32.0 | 17.2500 |
1 | 48.0 | 81.2833 |
2 | 36.0 | 17.9250 |
3 | 45.0 | 63.1000 |
4 | 45.0 | 18.0500 |
2-2. 데이터프레임 vs 데이터프레임
이번엔 타이타닉데이터의 아래쪽을 이용한다.
df.tail()
age | fare | |
---|---|---|
886 | 27.0 | 13.00 |
887 | 19.0 | 30.00 |
888 | NaN | 23.45 |
889 | 26.0 | 30.00 |
890 | 32.0 | 7.75 |
age열에 NaN이 존재한다.
addition = df + 10
addition.tail()
age | fare | |
---|---|---|
886 | 37.0 | 23.00 |
887 | 29.0 | 40.00 |
888 | NaN | 33.45 |
889 | 36.0 | 40.00 |
890 | 42.0 | 17.75 |
마찬가지로 NaN은 연산되지 않고 그대로 NaN이다.
10을 더했던 데이터프레임과 원래 데이터프레임을 다시 빼주면
substraction = addition - df
substraction.tail()
age | fare | |
---|---|---|
886 | 10.0 | 10.0 |
887 | 10.0 | 10.0 |
888 | NaN | 10.0 |
889 | 10.0 | 10.0 |
890 | 10.0 | 10.0 |
Reference
도서 [파이썬 머신러닝 판다스 데이터 분석]을 공부하며 작성하였습니다.
댓글남기기