나머지 객체간 연산
곱셈(mul, rmul), 나눗셈(div, rdiv), 나머지(mod, rmod), 거듭제곱(pow, rpow) 4개의 연산들도 마찬가지로 기본적인 파이썬 연산자와 거의 같지만 차별화되는 것은 fill_value 인수를 통해 계산 불가한 값을 채워 넣는다는 것이다.
행렬곱(dot)
행렬곱은 다음과 같이 사용된다.
DataFrame.dot(other)
선형대수학에서 배운 행렬곱과 같은 내용이다.
col1 col2 col1 col2 col1 col2
row1 A B x row1 a b = row1 Aa+bc Ab+Bd
row2 C D row2 c d row2 Ca+Dc Cb+Dd
간단한 2x2 짜리 DataFrame을 두개 만들어서 계산을 진행해보자.
col = ['col1','col2']
row = ['row1','row2']
data1 = [[1,2],[3,4]]
data2 = [[5,6],[7,8]]
df1 = pd.DataFrame(data=data1)
df2 = pd.DataFrame(data=data2)
print(df1)
>>
0 1
0 1 2
1 3 4
-------------------------------------------------------------------------------
print(df2)
>>
0 1
0 5 6
1 7 8
df3 = df1.dot(df2)
print(df3)
>>
0 1
0 19 22
1 43 50
계산과정은 아래와 같이 진행된다.
0 1 0 1 0 1 0 1
0 1 2 x 0 5 6 = 0 1*5+2*7 1*6+2*8 = 0 19 22
1 3 4 1 7 8 1 1*7+3*8 3*6+4*8 1 43 50
객체 내 연산
판다스 객체내 연산 함수인 round, sum, prod, abs, transpose, rank, diff, pct_package, expending, rolling, groupby, ewm에 대해서 알아보자.
round(): DataFrame 객체 내의 요소를 반올림하는 메서드이다.
sum(): 객체의 행이나 열의 총 합계를 구하는 메서드이다.
prod(): 객체의 행이나 열의 곱을 구하는 메서드이다.
abs(): 각 요소의 절댓값을 반환하는 메서드이다.
transpose() or T: Dataframe객체를 전치 하는 메서드이다. 만약 (n,m)짜리 DataFrame이라면 (0,0) 부터 (n,m)을 연결하는 대각선을 중심으로 뒤집는것과 같다.
rank(): 축에 대해서 순위를 매기는 메서드이다. 동일 순위일 경우 평균을 반환한다.
diff(): 한 객체 내에서 열과 열 / 행과 행의 차이를 출력하는 메서드이다.
pct_change(): 한 객체 내에서 행과 행의 차이를 현재값과의 백분율로 출력하는 메서드이다. 즉, (다음행 - 현재행)÷현재행 을 의미한다.
expanding(): 행이나 열의 값에 대해 누적으로 연산을 수행하는 메서드이다. df.expanding( ).sum( ) 처럼 추가 메서드를 이용하여 연산을 수행한다.
rolling(): 현재 열에 대하여 일정 크기의 창(window)를 이용하여 그 window안의 값을 추가 메서드를 통해 계산하는 메서드이다.
groupby(): 데이터를 그룹화하여 연산을 수행하는 메서드이다.
ewm(): 지수가중함수이다. 지수가중함수는 오래된 데이터에 지수감쇠를 적용하여 최근 데이터가 더 큰 영향을 끼지도록 가중치를 주는 함수이다. 보통 추가 메서드로 mean() 을 사용해서 지수가중평균으로 사용한다.
예시
round
col = ['col1','col2','col3']
row = ['row1','row2','row3']
data = np.random.rand(3,3)*100
df = pd.DataFrame(data=data, index=row, columns=col)
print(df)
>>
col1 col2 col3
row1 35.441830 30.006442 88.754181
row2 42.949147 62.131260 54.709369
row3 88.695079 27.138069 7.224099
#decimals = 0인 경우 0은 기본값으로 일의자리 까지 반올림
print(df.round(0))
>>
col1 col2 col3
row1 35.0 30.0 89.0
row2 43.0 62.0 55.0
row3 89.0 27.0 7.0
#decimals > 0인 경우 소수 n번째 자리 까지 반올림
print(df.round(2))
>>
col1 col2 col3
row1 35.44 30.01 88.75
row2 42.95 62.13 54.71
row3 88.70 27.14 7.22
#decimals < 0인 경우 10의 n승 자리 까지 반올림
print(df.round(-1))
>>
col1 col2 col3
row1 40.0 30.0 90.0
row2 40.0 60.0 50.0
row3 90.0 30.0 10.0
sum
col = ['col1','col2','col3']
row = ['row1','row2','row3']
data = [[1,2,3],[4,5,6],[7,np.NaN,9]]
df = pd.DataFrame(data=data,index=row,columns=col)
print(df)
>>
col1 col2 col3
row1 1 2.0 3
row2 4 5.0 6
row3 7 NaN 9
#열의 요소 합
print(df.sum(axis=0))
>>
col1 12.0
col2 7.0
col3 18.0
dtype: float64
#행의 요소 합
print(df.sum(axis=1))
>>
row1 6.0
row2 15.0
row3 16.0
dtype: float64
#skipna=False일 경우 NaN이 포함되는경우에는 NaN을 반환
print(df.sum(axis=0,skipna=False))
>>
col1 12.0
col2 NaN
col3 18.0
dtype: float64
#min_count 설정
print(df.sum(axis=1,min_count=3))
>>
row1 6.0
row2 15.0
row3 NaN
dtype: float64
min_count는 계산에 필요한 숫자의 최소 갯수를 의미한다. 즉, min_count=3이라면 NaN을 포함하는 행의 경우 숫자가 2개이기 때문에
skipna=True임에도 NaN을 출력하게 된다.
prod
col = ['col1','col2','col3']
row = ['row1','row2','row3']
data = [[1,2,3],[4,5,6],[7,np.NaN,9]]
df = pd.DataFrame(data=data,index=row,columns=col)
print(df)
>>
col1 col2 col3
row1 1 2.0 3
row2 4 5.0 6
row3 7 NaN 9
#열 요소 곱
print(df.prod(axis=0))
>>
col1 28.0
col2 10.0
col3 162.0
dtype: float64
#행 요소 곱
print(df.prod(axis=1))
>>
row1 6.0
row2 120.0
row3 63.0
dtype: float64
print(df.prod(axis=0, skipna=False))
>>
col1 28.0
col2 NaN
col3 162.0
dtype: float64
print(df.prod(axis=1, min_count=3))
>>
row1 6.0
row2 120.0
row3 NaN
dtype: float64
abs
col = ['col1','col2','col3']
row = ['row1','row2','row3']
data = [[-1,2,-3.5],[4,-5.5, 3+4j],[7,np.NaN,0]]
df = pd.DataFrame(data=data,index=row,columns=col)
print(df)
>>
col1 col2 col3
row1 -1 2.0 -3.5+0.0j
row2 4 -5.5 3.0+4.0j
row3 7 NaN 0.0+0.0j
print(df.abs( ))
>>
col1 col2 col3
row1 1 2.0 3.5
row2 4 5.5 5.0
row3 7 NaN 0.0
transpose
col = ['col1','col2','col3']
row = ['row1','row2','row3','row4']
data = [['A',1,2],['B',3,4],['C',5,6],['D',7,8]]
df = pd.DataFrame(data=data,index=row,columns=col)
print(df)
>>
col1 col2 col3
row1 A 1 2
row2 B 3 4
row3 C 5 6
row4 D 7 8
print(df.transpose())
>>
row1 row2 row3 row4
col1 A B C D
col2 1 3 5 7
col3 2 4 6 8
rank
data = [[5],[5],[pd.NA],[3],[-3.1],[5],[0.4],[6.7],[3]]
row = ['A★','B★','C','D☆','E','F★','G','H','I☆']
df = pd.DataFrame(data=data, index=row, columns=['Value'])
print(df)
>>
Value
A★ 5
B★ 5
C <NA>
D☆ 3
E -3.1
F★ 5
G 0.4
H 6.7
I☆ 3
average : D와 I의 경우 각각 3등 4등이기때문에 3.5 출력
min : A, B, F의 경우 각각 5등 6등 7등으로 가장 낮은등수인 5 출력
max : A, B, F의 경우 각각 5등 6등 7등으로 가장 높등수인 7 출력
first : 동점일경우 위에서부터 매김 D와 I 각각 3등 4등
dense : min처럼 동작하지만 등수가 순차적으로 증가
df['keep']=df['Value'].rank(na_option='keep')
df['top']=df['Value'].rank(na_option='top')
df['bottom']=df['Value'].rank(na_option='bottom')
df['pct']=df['Value'].rank(pct=True)
print(df)
>>
Value keep top bottom pct
A★ 5 6.0 7.0 6.0 0.7500
B★ 5 6.0 7.0 6.0 0.7500
C <NA> NaN 1.0 9.0 NaN
D☆ 3 3.5 4.5 3.5 0.4375
E -3.1 1.0 2.0 1.0 0.1250
F★ 5 6.0 7.0 6.0 0.7500
G 0.4 2.0 3.0 2.0 0.2500
H 6.7 8.0 9.0 8.0 1.0000
I☆ 3 3.5 4.5 3.5 0.4375
keep : Na요소에 NaN을 부여하여 그대로 둔다.
top : Na에게 가장 높은 순위를 부여합니다. 1등이 된것을 볼 수 있다.
bottom : Na에게 가장 높은 순위를 부여합니다. 9등이 된것을 볼 수 있다.
pct : True일 경우 백분위수로 표시한다.
diff
a = [1,2,3,4,5,6,7,8]
b = [1,2,4,8,16,32,64,128]
c = [8,7,6,5,4,3,2,1]
data = {"col1":a,"col2":b,"col3":c}
df = pd.DataFrame(data)
print(df)
>>
col1 col2 col3
0 1 1 8
1 2 2 7
2 3 4 6
3 4 8 5
4 5 16 4
5 6 32 3
6 7 64 2
7 8 128 1
print(df.diff(axis=0))
>>
col1 col2 col3
0 NaN NaN NaN # 뺄 바로 전 행이 없으므로 NaN
1 1.0 1.0 -1.0 # 1행 - 0행
2 1.0 2.0 -1.0 # 2행 - 1행
3 1.0 4.0 -1.0 # ...
4 1.0 8.0 -1.0
5 1.0 16.0 -1.0
6 1.0 32.0 -1.0
7 1.0 64.0 -1.0 # 7행 - 6행
print(df.diff(axis=1))
>>
col1 col2 col3 # col1은 뺄 이전 열이 없으므로 NaN출력
0 NaN 0 7 # col2 의 값은 기존 data의 col2 - col1
1 NaN 0 5 # col3 의 값은 기존 data의 col3 - col2
2 NaN 1 2
3 NaN 4 -3
4 NaN 11 -12
5 NaN 26 -29
6 NaN 57 -62
7 NaN 120 -127
print(df.diff(periods=3))
>>
col1 col2 col3
0 NaN NaN NaN #3칸 이전 값이 없으므로 NaN
1 NaN NaN NaN # ' '
2 NaN NaN NaN # ' '
3 3.0 7.0 -3.0 # 열3 - 열0의 값 출력
4 3.0 14.0 -3.0
5 3.0 28.0 -3.0
6 3.0 56.0 -3.0
7 3.0 112.0 -3.0 # 열7 - 열4의 값 출력
print(df.diff(periods=-2))
>>
col1 col2 col3
0 -2.0 -3.0 2.0 #열0 - 열2의 값 (마이너스이므로 뒤의값으로 계산)
1 -2.0 -6.0 2.0
2 -2.0 -12.0 2.0
3 -2.0 -24.0 2.0
4 -2.0 -48.0 2.0
5 -2.0 -96.0 2.0 # 열5 - 열7의 값
6 NaN NaN NaN # 2칸 뒤의 값이 없으므로 NaN
7 NaN NaN NaN # ' '
pct
a = [1,1,4,4,1,1]
b = [1,2,4,8,16,32]
c = [1,N,N,N,16,64]
data = {"col1":a,"col2":b,"col3":c}
df = pd.DataFrame(data)
print(df)
>>
col1 col2 col3
0 1 1 1.0
1 1 2 NaN
2 4 4 NaN
3 4 8 NaN
4 1 16 16.0
5 1 32 64.0
print(df.pct_change())
>>
col1 col2 col3
0 NaN NaN NaN # 첫행은 이전행이 없으므로 NaN출력
1 0.00 1.0 0.0 # col1의 경우 이전행과 값이 같으므로 (1-1)/1 = 0 출력
2 3.00 1.0 0.0 # col2의 경우 2배씩 커지므로 차이는 자기자신 즉 결과=1
3 0.00 1.0 0.0 # col3의 경우 결측치가 위의 값 기준으로 됨. (1-1)/1=0 출력
4 -0.75 1.0 15.0
5 0.00 1.0 3.0
print(df.pct_change(periods=2))
>>
col1 col2 col3
0 NaN NaN NaN
1 NaN NaN NaN # 0행, 1행은 2개전값이 없으므로 NaN 출력
2 3.00 3.0 0.0 # col1의 경우 (4-1)/1 = 3 출력
3 3.00 3.0 0.0 # col2의 경우 예를들어 (8-2)/2 = 3
4 -0.75 3.0 15.0
5 -0.75 3.0 63.0
print(df.pct_change(periods=-1))
>>
col1 col2 col3
0 0.00 -0.5 0.0000 # col2의 경우 예를들어 (2-1)/2 = -0.5
1 -0.75 -0.5 0.0000
2 0.00 -0.5 0.0000
3 3.00 -0.5 -0.9375
4 0.00 -0.5 -0.7500
5 NaN NaN NaN
fill_method='ffill'인 경우는 기본값으로 바로 윗값으로 결측치를 대체한다.
fill_method='bfill'인 경우는 바로 아랫값으로 결측치를 대체한다.
limit인수는 결측치를 몇개까지 대체할지 지정한다.
print(df.pct_change(fill_method='bfill'))
>>
col1 col2 col3
0 NaN NaN NaN
1 0.00 1.0 15.0
2 3.00 1.0 0.0
3 0.00 1.0 0.0 # col3의 경우 바로 아랫값인수로 결측치를 채우기때문에 16으로 채워집니다.
4 -0.75 1.0 0.0 # 때문에 (16-16)/16 해서 0입니다.
5 0.00 1.0 3.0
print(df.pct_change(limit=2))
>>
col1 col2 col3
0 NaN NaN NaN
1 0.00 1.0 0.0
2 3.00 1.0 0.0 # 2번째 결측치까지는 'ffill'에따라 1로 채워집니다.
3 0.00 1.0 NaN # 3번째 결측치는 limit=2이므로 NaN 그대로 둡니다.
4 -0.75 1.0 NaN
5 0.00 1.0 3.0
expanding
import numba
...
data = {'col1':[1,2,3,4],'col2':[3,7,5,6]}
idx = ['row1','row2','row3','row4']
df = pd.DataFrame(data = data, index = idx)
print(df)
>>
col1 col2
row1 1 3
row2 2 7
row3 3 5
row4 4 6
print(df.expanding().sum())
>>
col1 col2
row1 1.0 3.0
row2 3.0 10.0
row3 6.0 15.0
row4 10.0 21.0 #열마다 누적으로 sum을 진행
print(df.expanding(min_periods=4).sum())
>>
col1 col2
row1 NaN NaN
row2 NaN NaN
row3 NaN NaN
row4 10.0 21.0
#열기준 누적값 계산
print(df.expanding(axis=1).sum())
>>
col1 col2
row1 1.0 4.0
row2 2.0 9.0
row3 3.0 8.0
row4 4.0 10.0
#Numba는 파이썬 코드를 LLVM컴파일러를 이용해 머신코드로 바꾸어 수치연산을 가속해주는 라이브러리
print(df.expanding(method='table').sum(engine='numba'))
>>
col1 col2
row1 1.0 3.0 # 연산의 결과는 singe때와 동일하지만 대량의 데이터 연산에는 빠른 속도를 지원함.
row2 3.0 10.0
row3 6.0 15.0
row4 10.0 21.0
rolling
period = pd.period_range(start='2022-01-13 00:00:00',end='2022-01-13 02:30:00',freq='30T')
data = {'col1':[1,2,3,4,5,6],'col2':period}
idx = ['row1','row2','row3','row4','row5','row6']
df = pd.DataFrame(data= data, index = idx)
print(df)
>>
col1 col2
row1 1 2022-01-13 00:00
row2 2 2022-01-13 00:30
row3 3 2022-01-13 01:00
row4 4 2022-01-13 01:30
row5 5 2022-01-13 02:00
row6 6 2022-01-13 02:30
print(df.rolling(window=3).sum()) # 뒤에 추가 메서드를 이용하여 연산을 지정해주어야합니다.
>>
col1
row1 NaN # min_period의 크기는 지정하지 않을경우 window크기와 동일하므로 NaN출력
row2 NaN
row3 6.0 # 1행, 2행, 3행의 sum값 출력
row4 9.0 # 2행, 3행, 4행의 sum값 출력
row5 12.0
row6 15.0
'''
left : 3 ≤ x < 6
right : 3 < x ≤ 6
both : 3 ≤ x ≤ 6
neither : 3 < x < 6
'''
print(df.rolling(window=3, closed='left').sum())
>>
col1
row1 NaN
row2 NaN
row3 NaN
row4 6.0
row5 9.0
row6 12.0
print(df.rolling(window=3, closed='right').sum())
>>
col1
row1 NaN
row2 NaN
row3 6.0
row4 9.0
row5 12.0
row6 15.0
print(df.rolling(window=3, closed='both').sum())
>>
col1
row1 NaN
row2 NaN
row3 6.0
row4 10.0
row5 14.0
row6 18.0
print(df.rolling(window=3, closed='neither').sum())
>>
col1
row1 NaN
row2 NaN
row3 NaN
row4 NaN
row5 NaN
row6 NaN
print(df.rolling(window=3, closed='neither',min_periods=2).sum()) # min_period 지정
>>
col1
row1 NaN
row2 NaN
row3 3.0
row4 5.0
row5 7.0
row6 9.0
print(df.rolling(window=3, center=True).sum())
>>
col1
row1 NaN
row2 6.0
row3 9.0
row4 12.0
row5 15.0
row6 NaN
print(df.rolling(window=3, win_type='triang').sum()) # 삼각함수로 가중치 부여
>>
col1
row1 NaN
row2 NaN
row3 4.0
row4 6.0
row5 8.0
row6 10.0
print(df.rolling(window=3, win_type='gaussian').sum(std=3)) # 가우시안 분포로 가중치 부여
>>
col1
row1 NaN
row2 NaN
row3 5.783838
row4 8.675757
row5 11.567676
row6 14.459595
print(df.rolling(window='60T',on='col2').sum())
>>
col1 col2
row1 1.0 2022-01-13 00:00 # col2를 기준으로 rolling이 수행됨
row2 3.0 2022-01-13 00:30
row3 5.0 2022-01-13 01:00
row4 7.0 2022-01-13 01:30
row5 9.0 2022-01-13 02:00
row6 11.0 2022-01-13 02:30
groupby
idx=['A','A','B','B','B','C','C','C','D','D','D','D','E','E','E']
col=['col1','col2','col3']
data = np.random.randint(0,9,(15,3))
df = pd.DataFrame(data=data, index=idx, columns=col).reset_index()
print(df)
>>
index col1 col2 col3
0 A 5 0 7
1 A 2 6 2
2 B 1 1 8
3 B 1 6 6
4 B 3 2 3
5 C 1 0 8
6 C 8 4 1
7 C 1 5 5
8 D 3 3 7
9 D 5 7 7
10 D 1 6 5
11 D 4 0 0
12 E 0 5 6
13 E 2 7 7
14 E 0 7 0
print(df.groupby('index')) # index 컬럼에 대해서 groupby 수행
print(df.groupby('index').mean())
>>
col1 col2 col3
index
A 3.500000 3.000000 4.500000
B 1.666667 3.000000 5.666667
C 3.333333 3.000000 4.666667
D 3.250000 4.000000 4.750000
E 0.666667 6.333333 4.333333
print(df.groupby('index').count())
>>
col1 col2 col3
index
A 2 2 2
B 3 3 3
C 3 3 3
D 4 4 4
E 3 3 3
print(df.groupby('index').agg(['sum','mean']))
>>
col1 col2 col3
sum mean sum mean sum mean
index
A 7 3.500000 6 3.000000 9 4.500000
B 5 1.666667 9 3.000000 17 5.666667
C 10 3.333333 9 3.000000 14 4.666667
D 13 3.250000 16 4.000000 19 4.750000
E 2 0.666667 19 6.333333 13 4.333333
def top (df,n=2,col='col1'):
return df.sort_values(by=col)[-n:] #상위 n개 열을 반환하는 함수 top 생성
print(df.groupby('index').apply(top))
>>
index col1 col2 col3 # 인덱스와 index열이 중복
index
A 1 A 2 6 2
0 A 5 0 7
B 3 B 1 6 6
4 B 3 2 3
C 7 C 1 5 5
6 C 8 4 1
D 11 D 4 0 0
9 D 5 7 7
E 14 E 0 7 0
13 E 2 7 7
print(df.groupby('index',group_keys=False).apply(top))
>>
index col1 col2 col3 # 인덱스와의 중복이 제거
1 A 2 6 2
0 A 5 0 7
3 B 1 6 6
4 B 3 2 3
7 C 1 5 5
6 C 8 4 1
11 D 4 0 0
9 D 5 7 7
14 E 0 7 0
13 E 2 7 7
df_cat = pd.Categorical(df['index'], categories=['A','B','C','D','E','F']) # df의 index열에 대해서 A,B,C,D,E,F 로 Categorical을 하여 df_cat 생성
print(df_cat)
>>
['A', 'A', 'B', 'B', 'B', ..., 'D', 'D', 'E', 'E', 'E']
Length: 15
Categories (6, object): ['A', 'B', 'C', 'D', 'E', 'F'] # 값은 A~E 까지 있지만, 카테고리는 F까지 지정함.
print(df['col1'].groupby(df_cat).count())
>>
A 2
B 3
C 3
D 4
E 3
F 0 # index열에는 없지만, F까지 category 되었음. observed=False(기본값)인 경우 카테고리 전체가 표시됨.
Name: col1, dtype: int64
print(df['col1'].groupby(df_cat,observed=True).count())
>>
A 2
B 3
C 3
D 4
E 3
Name: col1, dtype: int64
print(df.groupby(['index'],as_index=False).sum())
>>
index col1 col2 col3
0 A 7 6 9
1 B 5 9 17
2 C 10 9 14
3 D 13 16 19
4 E 2 19 13
df.loc[6,'index'] = np.NaN
print(df)
>>
index col1 col2 col3
0 A 5 0 7
1 A 2 6 2
2 B 1 1 8
3 B 1 6 6
4 B 3 2 3
5 C 1 0 8
6 NaN 8 4 1
7 C 1 5 5
8 D 3 3 7
9 D 5 7 7
10 D 1 6 5
11 D 4 0 0
12 E 0 5 6
13 E 2 7 7
14 E 0 7 0
print(df.groupby('index').sum())
>>
col1 col2 col3
index
A 7 6 9
B 5 9 17
C 2 5 13
D 13 16 19
E 2 19 13
print(df.groupby('index',dropna=False).sum())
>>
col1 col2 col3
index
A 7 6 9
B 5 9 17
C 2 5 13
D 13 16 19
E 2 19 13
NaN 8 4 1 # NaN이 표시됩니다.
idx = [['idx1','idx1','idx2','idx2','idx2'],['row1','row2','row1','row2','row3']]
col = ['col1','col2','col2']
data = np.random.randint(0,9,(5,3))
df = pd.DataFrame(data=data, index = idx, columns = col).rename_axis(index=['lv0','lv1'])
print(df)
>>
col1 col2 col2
lv0 lv1
idx1 row1 7 3 7
row2 2 1 6
idx2 row1 1 7 2
row2 3 5 7
row3 5 1 8
print(df.groupby(level=1).sum())
>>
col1 col2 col2
lv1
row1 8 10 9
row2 5 6 13
row3 5 1 8
print(df.groupby(['lv1','lv0']).sum())
>>
col1 col2 col2
lv1 lv0
row1 idx1 7 3 7
idx2 1 7 2
row2 idx1 2 1 6
idx2 3 5 7
row3 idx2 5 1 8
ewm
data = {'val':[1,4,2,3,2,5,13,10,12,14,np.NaN,16,12,20,22]}
df = pd.DataFrame(data).reset_index()
print(df)
>>
index val
0 0 1.0
1 1 4.0
2 2 2.0
3 3 3.0
4 4 2.0
5 5 5.0
6 6 13.0
7 7 10.0
8 8 12.0
9 9 14.0
10 10 NaN
11 11 16.0
12 12 12.0
13 13 20.0
14 14 22.0
df2 = df.assign(ewm=df['val'].ewm(alpha=0.3).mean()) # val열에 ewm 메서드적용 후 df에 추가
ax = df.plot(kind='bar',x='index',y='val') # ax에 df의 bar chart 생성
ax2= df2.plot(kind='line',x='index', y='ewm', color='red', ax=ax) # ax2에 df2의 line chart 생성후 ax에 추가
plt.show() # 그래프 출력
df2 = df.assign(ewm_a_low=df['val'].ewm(alpha=0.1).mean()) #alpha=0.1로 df2 생성
df3 = df.assign(ewm_a_high=df['val'].ewm(alpha=0.7).mean()) #alpha=0.7로 df3 생성
ax = df.plot(kind='bar',x='index',y='val')
ax2= df2.plot(kind='line',x='index', y='ewm_a_low', color='red', ax=ax) # alpha=0.1 은 적색
ax3= df3.plot(kind='line',x='index', y='ewm_a_high', color='green', ax=ax) # alpha=0.7 은 녹색
plt.show()
alpha가 0.1인 적색선보다. alpha가 0.7인 녹색선이 급격한 변화에 더 민감한 것을 볼 수 있다.
span은 기간을 지정하여 평활계수를 계산하는 인수입니다. 계산식은 a = 2/(span+1)으로 계산 기간이 길어질수록 a가 작아집니다.
df2 = df.assign(span_4=df['val'].ewm(span=4).mean())
df3 = df.assign(span_8=df['val'].ewm(span=8).mean())
ax = df.plot(kind='bar',x='index',y='val')
ax2= df2.plot(kind='line',x='index', y='span_4', color='red', ax=ax)
ax3= df3.plot(kind='line',x='index', y='span_8', color='green', ax=ax)
plt.show()
span이 긴 녹색이 span이 짧은 적색선보다 덜 민감하게 반응하는 것을 확인 할 수 있다.
span이 길면 그만큼 과거의 데이터의 영향이 커지기 때문이다.
com 은 질량중심 감쇠법으로 평활계수를 계산하는 인수이다. 계산식은 a=1/(1+com)으로 com이 커질수록 a가 작아진다.
df2 = df.assign(com_2=df['val'].ewm(com=2).mean())
df3 = df.assign(com_10=df['val'].ewm(com=10).mean())
ax = df.plot(kind='bar',x='index',y='val')
ax2= df2.plot(kind='line',x='index', y='com_2', color='red', ax=ax)
ax3= df3.plot(kind='line',x='index', y='com_10', color='green', ax=ax)
plt.show()
com이 큰 녹색이 com이 작은 적색보다 덜 민감하게 반응하는 것을 확인할 수 있다.
com이 클 수록 과거의 데이터의 가중치가 커지기 때문이다.
halflife인수는 반감기를 이용하여 평활계수를 계산하는 인수입니다. 계산식은 a=1-e^(-ln(2)/halflife) 으로 halflife가 길어질수록 a가 작아집니다.
df2 = df.assign(harf_2=df['val'].ewm(halflife=2).mean())
df3 = df.assign(harf_5=df['val'].ewm(halflife=5).mean())
ax = df.plot(kind='bar',x='index',y='val')
ax2= df2.plot(kind='line',x='index', y='harf_2', color='red', ax=ax)
ax3= df3.plot(kind='line',x='index', y='harf_5', color='green', ax=ax)
plt.show()
halflife 반감기가 길수록(녹색) 더욱 둔감한 그래프가 그려지는것을 확인할 수 있다.
df2 = df.assign(adj_True=df['val'].ewm(alpha=0.2,adjust=True).mean())
df3 = df.assign(adj_False=df['val'].ewm(alpha=0.2,adjust=False).mean())
ax = df.plot(kind='bar',x='index',y='val')
ax2= df2.plot(kind='line',x='index', y='adj_True', color='red', ax=ax)
ax3= df3.plot(kind='line',x='index', y='adj_False', color='green', ax=ax)
plt.show()
adjust는 상대적 가중치의 불균형을 해소하기위해 조정계수로 나눌지의 여부이다. 대체로 값이 많을수록 adjust를 하는것이 유리하다.
ignore_na는 결측치가 존재할 경우 가중치를 어떻게 설정할지 정하는 인수이다.
[x0, None, x1] 일때, 인 경우 ignore_na = False 이면 절대위치를 기반으로 하며, x0와 x2의 가중치는 adjust = [ True인경우 (1-a)^2와 1 / False인 경우 (1-a)^2와 a ] 이다.
[x0, None, x1] 일때, 인 경우 ignore_na = False 이면 절대위치를 기반으로 하며, x0와 x2의 가중치는 adjust = [ True인경우 (1-a)와 1 / False인 경우 (1-a)와 a ] 이다.
df2 = df.assign(ignore_na_True=df['val'].ewm(alpha=0.2,ignore_na=True).mean())
df3 = df.assign(ignore_na_False=df['val'].ewm(alpha=0.2,ignore_na=False).mean())
ax = df.plot(kind='bar',x='index',y='val')
ax2= df2.plot(kind='line',x='index', y='ignore_na_True', color='red', ax=ax)
ax3= df3.plot(kind='line',x='index', y='ignore_na_False', color='green', ax=ax)
plt.show()
'Sketch (Programming Language) > Python' 카테고리의 다른 글
Baekjoon Training #14888 (0) | 2023.08.27 |
---|---|
Pandas(3) (0) | 2023.08.23 |
Pandas(1) (0) | 2023.08.20 |
Baekjoon Training #1904 (0) | 2023.08.18 |
Baekjoon Training #12865 (0) | 2023.08.06 |