shift
메서드는 시계열 데이터의 데이터나 인덱스를 원하는 기간만큼 쉬프트 하는 메서드 입니다.
freq
인수를 입력하지 않으면 데이터가 이동하고, 인수값을 입력하게되면 인덱스가 freq
값 만큼 이동하게됩니다.
periods
: 이동할 기간입니다.
freq
: 입력 할 경우 인덱스가 이동하게 됩니다. Y, M, D, H, T, S
나 Timestamp, 'Infer'등이 올 수 있습니다.
fill_value
: shift로 인해 생긴 결측치를 대체할 값입니다.
먼저 기본적인 사용법 예시를위하여 5x3 짜리 데이터를 만들어보겠습니다.
pd.date_range
를 이용해 기준시간에 대해 일정 간격을 가진 datetime index를 생성하겠습니다.
idx = pd.date_range(start='2022-01-01',periods=5,freq='2D')
# 2일 간격으로 5행의 인덱스 생성
data={'col1':[10,20,30,40,50],'col2':[1,3,6,7,9],'col3':[43,13,82,47,31]}
df = pd.DataFrame(data=data, index=idx)
print(df)
>>
col1 col2 col3
2022-01-01 10 1 43
2022-01-03 20 3 13
2022-01-05 30 6 82
2022-01-07 40 7 47
2022-01-09 50 9 31
period 인수 사용할 경우 행 기준으로 이동
print(df.shift(periods=2,))
>>
col1 col2 col3
2022-01-01 NaN NaN NaN
2022-01-03 NaN NaN NaN
2022-01-05 10.0 1.0 43.0
2022-01-07 20.0 3.0 13.0
2022-01-09 30.0 6.0 82.0
axis 사용
print(df.shift(periods=2,axis=1))
>>
col1 col2 col3
2022-01-01 NaN NaN 10
2022-01-03 NaN NaN 20
2022-01-05 NaN NaN 30
2022-01-07 NaN NaN 40
2022-01-09 NaN NaN 50
fill_value
인수를 사용하면, shift되면서 NaN
처리된 결측치를 원하는 값으로 채울 수 있습니다.
print(df.shift(periods=2, axis=1,fill_value='-'))
>>
col1 col2 col3
2022-01-01 - - 10
2022-01-03 - - 20
2022-01-05 - - 30
2022-01-07 - - 40
2022-01-09 - - 50
freq 인수의 사용
freq
인수를 설정해주면, 데이터가 아닌 인덱스가 freq
에 입력한 값 만큼 쉬프트 됩니다.
print(df.shift(periods=3,freq='D'))
# 일 기준 3기간 이동. 즉, 3일 이동
>>
#인덱스에 있는 년도와 날짜가 3일씩 이동된걸 알 수 있다
col1 col2 col3
2022-01-04 10 1 43
2022-01-06 20 3 13
2022-01-08 30 6 82
2022-01-10 40 7 47
2022-01-12 50 9 31
freq='infer'
인 경우, 현재 인덱스의 간격을 분석해서 적당한 freq
를 추론해줍니다.
print(df.shift(periods=3,freq='infer'))
#인덱스의 날짜 간격이 처음 데이터프레임을 생성할때 2D라는 간격으로 설정했기 때문에
#infer로 추론한 간격은 2D가 된다
>>
col1 col2 col3
2022-01-07 10 1 43
2022-01-09 20 3 13
2022-01-11 30 6 82
2022-01-13 40 7 47
2022-01-15 50 9 31
위의 예시의 경우, 인덱스의 인터벌(간격)이 2일이므로 freq='2D'
로 추론하였으며, period=3
이기 때문에 6일이 쉬프트 된것을 알 수 있습니다.
DatetimeIndex와 PeriodIndex의 차이는 Datetimeindex는 연,월,일과 같은 모든 시간을 표시하지만 Periodindex는 그중에서 잘라서 출력해 줄 수 있
to_period
메서드는 DatetimeIndex를 PeriodIndex로 변환하는 메서드 입니다.
freq
: 원하는 시간 단위로 변환할 수 있습니다.
axis
: 변환할 기준 축 입니다.
copy
: 사본을 형성할지 여부입니다.
idx = pd.date_range(start='2021-08-01',periods=5,freq='45D') # 45일 간격 인덱스
>>
DatetimeIndex(['2021-08-01', '2021-09-15', '2021-10-30', '2021-12-14',
'2022-01-28'],
dtype='datetime64[ns]', freq='45D') # 형식은 datetime64
freq
값을 지정하여 원하는 시간간격으로 출력이 가능합니다.
freq="Y"
print(idx.to_period("Y"))
>>
PeriodIndex(['2021', '2021', '2021', '2021', '2022'], dtype='period[A-DEC]')
freq="M"
print(idx.to_period("M"))
>>
PeriodIndex(['2021-08', '2021-09', '2021-10', '2021-12', '2022-01'], dtype='period[M]')
freq="W"
print(idx.to_period("W"))
>>
PeriodIndex(['2021-07-26/2021-08-01', '2021-09-13/2021-09-19',
'2021-10-25/2021-10-31', '2021-12-13/2021-12-19',
'2022-01-24/2022-01-30'],
dtype='period[W-SUN]')
freq="H"
print(idx.to_period("H"))
>>
PeriodIndex(['2021-08-01 00:00', '2021-09-15 00:00', '2021-10-30 00:00',
'2021-12-14 00:00', '2022-01-28 00:00'],
dtype='period[H]')
xs
는 멀티인덱스 객체에 대해서 하위 분류를 출력하는 메서드입니다.
key
: 분류의 기준이 되는 값입니다. Multi Index의 값을 지정합니다.
axis
: 하위 분류 출력의 기준이되는 축을 지정합니다.
level
: 멀티인덱스에 키가 부분적으로 포함되어있는경우, 레벨 지정을 통해 분류할 수 있습니다.
drop_level
: 기본값은 True로 필터링하는 값을 제외하고 하위 분류만 출력합니다. False면 필터링하는 값이 있는 분류까지 출력합니다.
data = {'col1':[0,1,2,3,4], 'col2':[5,6,7,8,9],
'level0':['A','A','A','B','B'],
'level1':['X','X','Y','Y','Z'],
'level2':['a','a','b','c','a']}
df = pd.DataFrame(data=data)
df = df.set_index(['level0', 'level1', 'level2'])
print(df)
>>
col1 col2
level0 level1 level2
A X a 0 5
a 1 6
Y b 2 7
B Y c 3 8
Z a 4 9
기본적인 사용법
기본적으로 key
값을 지정하면 해당 값의 하위 분류를 출력합니다.
print(df.xs(key='A'))
>>
col1 col2
level1 level2
A X a 0 5
a 1 6
Y b 2 7
#B Y c 3 8
# Z a 4 9
#여기는 제외된
key
값을 여러 값으로 지정할 수 도 있습니다.
print(df.xs(key=('A','X')))#의 하위분류를 하기 때문에
>>
col1 col2
level2
a 0 5
a 1 6
col1 col2
level0 level1 level2
A X /a 0 5
/a 1 6
Y /b 2 7
////////////////////
B Y c 3 8
Z a 4 9
level
을 지정하여 하위분류를 진행할 수 있습니다.
print(df.xs(key='Y',level=1))
>>
col1 col2
level0 level2
A b 2 7
B c 3 8
col1 col2
level0 level1 level2
A X a 0 5
a 1 6
/////////////////////////////////
Y! b 2 7
B Y! c 3 8
/////////////////////////////////
Z a 4 9
drop_level=True
로 할 경우 key
값으로 지정된 레벨을 포함해서 줄력합니다.
print(df.xs(key='Y',level=1,drop_level=True)) #False가 기본이다
>>
col1 col2
level0 level1 level2
A Y b 2 7
B Y c 3 8
stack
메서드는 열을 피벗하여 하위 인덱스로 변환하는 메서드입니다.
level
: MultiColumns의 경우 하위인덱스로 변환할 열의 레벨입니다. 기본값은 -1로 최하위 레벨이 선택됩니다. dropna
: {True / False} 기본값은 True로 피벗화로인해 생성된 하위인덱스의 모든 값이 결측치(NaN)인 경우 해당 열이 제거됩니다.
data = [[0,1,2,3],[4,5,6,7],[8,9,10,11],[12,13,14,15]]
idx = [['idx1','idx1','idx2','idx2'],['row1','row2','row3','row4']]
col = [['val1','val1','val2','val2'],['col1','col2','col3','col4']]
df = pd.DataFrame(data = data, index = idx, columns = col)
print(df)
>>
val1 val2
col1 col2 col3 col4
idx1 row1 0 1 2 3
row2 4 5 6 7
idx2 row3 8 9 10 11
row4 12 13 14 15
기본적인 사용법
'level'의 기본값은 '-1'로 최하위 레벨이 선택됩니다. 위 df에서는 level=1이 최하위 계층이기 때문에,
df.stack( ) = df.stack(level=1)
입니다. 함수 실행 시 level=1
의 열이 인덱스로 피벗된걸 확인할 수 있습니다.
print(df.stack())# 있지 않은 값은 결측값이 된걸 볼 수 있다
>>
val1 val2
idx1 row1 col1 0.0 NaN
col2 1.0 NaN
col3 NaN 2.0
col4 NaN 3.0
row2 col1 4.0 NaN
col2 5.0 NaN
col3 NaN 6.0
col4 NaN 7.0
idx2 row3 col1 8.0 NaN
col2 9.0 NaN
col3 NaN 10.0
col4 NaN 11.0
row4 col1 12.0 NaN
col2 13.0 NaN
col3 NaN 14.0
col4 NaN 15.0
level=0
인 경우 아래와같이 'val1', 'val2'가 포함된 level=0
의 열이 피벗화 되는것을 볼 수 있습니다.
print(df.stack(level=0))# 레벨 0일 경우 val1,val2가 피벗화 된걸 확인 할 수 있다
>>
col1 col2 col3 col4
idx1 row1 val1 0.0 1.0 NaN NaN
val2 NaN NaN 2.0 3.0
row2 val1 4.0 5.0 NaN NaN
val2 NaN NaN 6.0 7.0
idx2 row3 val1 8.0 9.0 NaN NaN
val2 NaN NaN 10.0 11.0
row4 val1 12.0 13.0 NaN NaN
val2 NaN NaN 14.0 15.0
level=(0,1)
처럼 튜플로 묶어줄 경우 해당되는 모든 계층에 대해 피벗화를 할 수 있습니다.
모든 계층(레벨)이 피벗화 될 경우 Serise 객체로 출력됩니다.
print(df.stack(level=(0,1)))
>>
idx1 row1 val1 col1 0.0
col2 1.0
val2 col3 2.0
col4 3.0
row2 val1 col1 4.0
col2 5.0
val2 col3 6.0
col4 7.0
idx2 row3 val1 col1 8.0
col2 9.0
val2 col3 10.0
col4 11.0
row4 val1 col1 12.0
col2 13.0
val2 col3 14.0
col4 15.0
dtype: float64
dropna인수의 사용
dropna
인수는 기본값이 True
로 열이 피벗화된 인덱스의 값이 NaN
이면 해당 열을 출력하지 않습니다.
예시를 위해 간단한 2x2 짜리 데이터를 만들어보겠습니다.
data = [[np.NaN,1],[2,3]]
idx = ['row1','row2']
col = ['col1','col2']
df = pd.DataFrame(data = data, index = idx, columns = col)
print(df)
>>
col1 col2
row1 NaN 1
row2 2.0 3
stack
메서드를 사용할 경우 col1
, col2
열이 인덱스로 피벗화되는데, row1-col1
의 값은 NaN
이기 때문에 출력에서는 아래와같이 제거됩니다.
print(df.stack())#결측값이 제거된걸 볼 수 있다, 모든 열이 피벗화가 되었기 때문에 시리즈로 출력한다
>>
row1 col2 1.0
row2 col1 2.0
col2 3.0
dtype: float64
dropna=True
로 출력 할 경우 결측값을 갖는 열 또한 정상적으로 출력되는것을 볼 수 있습니다.
print(df.stack(dropna=False))#결측값이 포함되어 정상적으로 출력되는걸 확인할 수 있다
>>
row1 col1 NaN
col2 1.0
row2 col1 2.0
col2 3.0
dtype: float64
unstack
메서드는 행을 언피벗하여 하위 열로 변환하는 메서드입니다.
level
: MultiIndex의 경우 하위열로 변환할 행의 레벨입니다. 기본값은 -1로 최하위 레벨이 선택됩니다.
fill_value
: 생성된 열의 값에 결측치가 있을 경우 대체할 값입니다.
data =[1,2,3,4,5]
idx = [['idx1','idx1','idx2','idx2','idx2'],['row1','row2','row1','row2','row3']]
df = pd.Series(data=data, index = idx)
print(df)
>>
idx1 row1 1
row2 2
idx2 row1 3
row2 4
row3 5
dtype: int64
level
은 기본값이 -1이며, 최하위 레벨의 행에 대해 열로 언피벗 합니다.
아래 예시를 보면 최 하위 계층인 row1
,row2
가 속한 인덱스가 열로 언피벗 된것을 확인할 수 있습니다.
print(df.unstack()) #출력을 보면 row가 위로 올라가면서 언피벗된걸 확인할 수 있
>>
row1 row2 row3
idx1 1.0 2.0 NaN
idx2 3.0 4.0 5.0
fill_value
인수를 사용할 경우, 언피벗으로 인해 행성된 결측치를 특정 값으로 지정할 수 있습니다.
print(df.unstack(fill_value='-'))#결측값을 특정 값으로 지정해준다 피벗화에서도 똑같이 가능하다
>>
row1 row2 row3
idx1 1 2 -
idx2 3 4 5
좀 더 큰 다중인덱스에 대해서 예시를 들어보기위해 4레벨의 멀티인덱스를 생성해보겠습니다.
data = [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15]
level0=['idx1','idx1','idx1','idx1','idx1','idx1','idx1','idx1',
'idx2','idx2','idx2','idx2','idx2','idx2','idx2','idx2']
level1=['row1','row1','row1','row1','row2','row2','row2','row2',
'row3','row3','row3','row3','row4','row4','row4','row4']
level2=['val1','val1','val2','val2','val1','val1','val2','val2',
'val1','val1','val2','val2','val1','val1','val2','val2']
level3=['col1','col2','col3','col4','col1','col2','col3','col4',
'col1','col2','col3','col4','col1','col2','col3','col4']
idx = [level0,level1,level2,level3]
df = pd.Series(data =data, index =idx)
print(df)
>>
idx1 row1 val1 col1 0
col2 1
val2 col3 2
col4 3
row2 val1 col1 4
col2 5
val2 col3 6
col4 7
idx2 row3 val1 col1 8
col2 9
val2 col3 10
col4 11
row4 val1 col1 12
col2 13
val2 col3 14
col4 15
dtype: int64
val1
, val2
가 속한 level=2
로 unstack
메서드를 실행해보겠습니다.
print(df.unstack(level=2))#level=2가 언피벗화가 된걸 확일할 수 있다
>>
val1 val2
idx1 row1 col1 0.0 NaN
col2 1.0 NaN
col3 NaN 2.0
col4 NaN 3.0
row2 col1 4.0 NaN
col2 5.0 NaN
col3 NaN 6.0
col4 NaN 7.0
idx2 row3 col1 8.0 NaN
col2 9.0 NaN
col3 NaN 10.0
col4 NaN 11.0
row4 col1 12.0 NaN
col2 13.0 NaN
col3 NaN 14.0
col4 NaN 15.0
level
에 튜플을 이용하여 Multi Columns로 unstack
을 실행할 수 있습니다.
print(df.unstack(level=(2,3)))
>>
col1 col2 col3 col4
idx1 row1 0 1 2 3
row2 4 5 6 7
idx2 row3 8 9 10 11
row4 12 13 14 15
swaplevel
메서드는 Multi Index (또는 Munti Columns)에서 두 인덱스의 순서를 변경하는 메서드입니다.
i , j
: 순서를 변경할 두 인덱스의 레벨입니다. 기본적으로 제일 낮은 두 레벨의 인덱스가 교환됩니다.(-2, -1)
axis
: 기본값은 0으로 axis=1
로 변경할 경우 Multi Columns에 대해 메서드가 수행됩니다.
data = {'col':[0,1,2,3,4,5]}
level0 = ['idx1','idx1','idx1','idx1','idx2','idx2']
level1 = ['val1','val1','val2','val2','val3','val4']
level2 = ['row1','row2','row3','row4','row5','row6']
idx = [level0, level1, level2]
df = pd.DataFrame(data = data, index=idx)
print(df)
>>
col
idx1 val1 row1 0
row2 1
val2 row3 2
row4 3
idx2 val3 row5 4
val4 row6 5
기본적인 사용법
i, j
인수에 아무것도 입력하지 않는다면, 제일 낮은 두 레벨의 인덱스가 교환됩니다.
print(df.swaplevel())
>>
col
idx1 row1 val1 0 # 인덱스의 level1과 level2의 위치가 바뀐것을 확인.
row2 val1 1
row3 val2 2
row4 val2 3
idx2 row5 val3 4
row6 val4 5
인수로 한 숫자만 입력하게되면, 가장 낮은 레벨의 인덱스와 인수로 입력한 숫자에 해당하는 레벨의 인덱스가 교환됩니다.
print(df.swaplevel(0))
>>
col
row1 val1 idx1 0 #인덱스의 level0과 최하위 레벨의 인덱스의 위치가 바뀐것을 확인.
row2 val1 idx1 1
row3 val2 idx1 2
row4 val2 idx1 3
row5 val3 idx2 4
row6 val4 idx2 5
두 값을 지정하여 원하는 인덱스끼리의 교환이 가능합니다. 레벨명이 있다면 레벨명을 쓸 수도 있습니다.
print(df.swaplevel(i=0,j=1))#이거는 왜 지정하는지 모르겠다 컬러쪽에 레벨이 하나 더 있어도 axis로 구별을 안하면 행과 열도 같이 스왑 되는게 똑같다 굳이 왜 지정을 해서 바꾸는지 이해를 못함
>>
col
val1 idx1 row1 0 # 레벨0과 레벨1의 위치가 바뀐것을 확인.
row2 1
val2 idx1 row3 2
row4 3
val3 idx2 row5 4
val4 idx2 row6 5
droplevel
메서드는 Multi Index나 Multi Columns에서 특정 레벨을 제거하는 메서드입니다.
level
: 제거할 단계 입니다.
axis
: 특정 레벨을 제거할 축 입니다.
data= [[0,1,2,3],[4,5,6,7],[8,9,10,11],[12,13,14,15]]
idx = [['idx1','idx1','idx2','idx2'],['row1','row2','row3','row4']]
col = [['col1','col1','col2','col2'],['val1','val2','val3','val4']]
df = pd.DataFrame(data=data, index = idx, columns = col)
print(df)
>>
col1 col2
val1 val2 val3 val4
idx1 row1 0 1 2 3
row2 4 5 6 7
idx2 row3 8 9 10 11
row4 12 13 14 15
기본적인 사용법
level
에 제거를 원하는 레벨을 입력함으로서 해당 레벨을 제거하여 값을 출력할 수 있습니다.
level=0
인 경우 Multi Index의 level=0인 idx1
, idx2
가 제거된 것을 알 수 있습니다.
print(df.droplevel(axis=0,level=0))
>>
col1 col2
val1 val2 val3 val4
row1 0 1 2 3 # idx가 제거됨
row2 4 5 6 7
row3 8 9 10 11
row4 12 13 14 15
level=1
인 경우 Multi Index의 level=1인 row1
, row2
, row3
, row4
가 제거된 것을 알 수 있습니다.
print(df.droplevel(axis=0,level=1))
>>
col1 col2
val1 val2 val3 val4
idx1 0 1 2 3 # row가 제거됨
idx1 4 5 6 7
idx2 8 9 10 11
idx2 12 13 14 15
axis=1
인 경우 Multi Columns에 대해서 특정 레벨을 제거 할 수 있습니다.
print(df.droplevel(axis=1,level=0))
>>
val1 val2 val3 val4 # col이 제거됨
idx1 row1 0 1 2 3
row2 4 5 6 7
idx2 row3 8 9 10 11
row4 12 13 14 15
Copyprint(df.droplevel(axis=1,level=1))
>>
col1 col1 col2 col2 # vol이 제거됨
idx1 row1 0 1 2 3
row2 4 5 6 7
idx2 row3 8 9 10 11
row4 12 13 14 15