23년 4월의 공부 - index를 이용한 조건 검색, pd.date_range, pd.DataFrame.shift
포스트
취소

23년 4월의 공부 - index를 이용한 조건 검색, pd.date_range, pd.DataFrame.shift

2023년 4월 동안 검색하고 공부한 것들을 정리한 내용입니다.

Summary

  1. pd.DataFrame에서 특정 변수에 대한 조건을 이용해 검색할 때, index를 활용하면 속도가 빠름.
  2. pd.date_range() : 시작 시간에서 지정한 개수 또는 주기에 대한 DatetimeIndex 출력.
  3. 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
이 기사는 저작권자의 CC BY 4.0 라이센스를 따릅니다.