2023년 4월 동안 검색하고 공부한 것들을 정리한 내용입니다.
Summary
- pd.DataFrame에서 특정 변수에 대한 조건을 이용해 검색할 때, index를 활용하면 속도가 빠름.
pd.date_range()
: 시작 시간에서 지정한 개수 또는 주기에 대한 DatetimeIndex 출력.pd.DataFrame.shift()
: index 또는 column을 지정한 수만큼 이동.freq
옵션을 이용하면 데이터를 재정렬하고, 이용하지 않으면 재정렬하지 않음.
1. Index of dataframe
SQL에서 index로 where 조건을 지정하는 경우, full scan을 피하면서 속도에서 이점이 있습니다. 이런 특성은 pandas.DataFrame에서도 동일합니다.
먼저 테스트에 이용할 데이터프레임을 만들어 줍니다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
import numpy as np
import pandas as pd
import time
import random
import string
n = 1000000
rint = [random.randint(0,100) for i in np.arange(n)]
rtext1 = [''.join(random.choices(string.ascii_lowercase + string.digits, k=10)) for i in np.arange(n)]
rtext2 = [''.join(random.choices(string.ascii_lowercase + string.digits, k=10)) for i in np.arange(n)]
df = pd.DataFrame(np.stack([np.array(rint), np.array(rtext1), np.array(rtext2)], axis=1), columns=['val_int', 'val_str1', 'val_str2'])
df['val_int'] = df['val_int'].astype('int')
df_aft = df.set_index('val_int')
print(df)
# val_int val_str1 val_str2
# 0 28 yngtm09bfy f4evk6mk87
# 1 76 qdy58t40ru yax8s0foli
# 2 55 8kfp3lth63 7256ibm4d6
# 3 43 xas52m9xdx k28x5hzp5k
# 4 33 xkz4ewh9cz 9pi7p287q9
# ... ... ... ...
# 999995 26 zk1ystfo7m snyjncc2fg
# 999996 72 n4c43dzf4a pwc5slmcht
# 999997 12 zuh48z3rod hse62kd4dp
# 999998 73 zn4lw4ppn5 w0ldwfzp7f
# 999999 15 i2bcd7irku vsaqsto2n6
index를 이용하지 않고 특정 변수에 대한 조건을 검색한 결과입니다.
1
2
3
4
5
6
7
8
%%time
for i in range(len(df)):
if divmod(df.iloc[i,0], 2) == 0:
print(df.iloc[i,:])
else:
continue
# CPU times: user 25.3 s, sys: 54.1 ms, total: 25.4 s
# Wall time: 26.4 s
다음으로 index를 이용하여 조건을 검색한 결과입니다.
1
2
3
4
5
6
7
8
%%time
for i in range(len(df_aft)):
if divmod(df_aft.index[i], 2) == 0:
print(df_aft.iloc[i])
else:
continue
# CPU times: user 2.03 s, sys: 9.6 ms, total: 2.04 s
# Wall time: 3.7 s
2. pd.date_range
pd.date_range
는 지정한 시작 시간(start)에서 필요한 개수(period) 또는 주기(freq)에 대한 시간에 대한 시퀀스(DatetimeIndex 객체)를 출력하는 함수입니다. freq에는 다양한 시간에 대한 alias들이 있으며, 자세한 내용은 링크를 참고하시면 됩니다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
import pandas as pd
pd.date_range(start='2022-01-01', end='2022-01-06')
# DatetimeIndex(['2022-01-01', '2022-01-02', '2022-01-03', '2022-01-04',
# '2022-01-05', '2022-01-06'],
# dtype='datetime64[ns]', freq='D')
pd.date_range(start='2022-01-01', periods=5)
# DatetimeIndex(['2022-01-01', '2022-01-02', '2022-01-03', '2022-01-04',
# '2022-01-05'],
# dtype='datetime64[ns]', freq='D')
pd.date_range(start='2022-01-01', periods=5, freq='3MS')
# DatetimeIndex(['2022-01-01', '2022-04-01', '2022-07-01', '2022-10-01',
# '2023-01-01'],
# dtype='datetime64[ns]', freq='3MS')
pd.date_range(start='2022-01-01', periods=5, freq=pd.offsets.MonthEnd(3))
# DatetimeIndex(['2022-01-31', '2022-04-30', '2022-07-31', '2022-10-31',
# '2023-01-31'],
# dtype='datetime64[ns]', freq='3M')
3. pd.DataFrame.shift
pd.DataFrame.shift
는 pd.DataFrame의 index 또는 column을 지정한 수(periods) 또는 시간(freq) 만큼 이동시키는 함수입니다. freq
옵션이 주어질 경우에는 index 값을 다시 정렬하여 데이터를 보존시키고, freq
옵션을 지정하지 않는 경우는 index가 재정렬 되지 않습니다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
import pandas as pd
df = pd.DataFrame({"Col1": [10, 20, 15, 30, 45],
"Col2": [13, 23, 18, 33, 48],
"Col3": [17, 27, 22, 37, 52]},
index=pd.date_range("2020-01-01", "2020-01-05"))
print(df.shift(periods=3))
Col1 Col2 Col3
# 0 NaN NaN NaN
# 1 NaN NaN NaN
# 2 NaN NaN NaN
# 3 10.0 13.0 17.0
# 4 20.0 23.0 27.0
print(df.shift(periods=1, axis="columns"))
# Col1 Col2 Col3
# 0 NaN 10 13
# 1 NaN 20 23
# 2 NaN 15 18
# 3 NaN 30 33
# 4 NaN 45 48
print(df.shift(periods=3, freq="D"))
# Col1 Col2 Col3
# 2020-01-04 10 13 17
# 2020-01-05 20 23 27
# 2020-01-06 15 18 22
# 2020-01-07 30 33 37
# 2020-01-08 45 48 52