[pandas] 기본 문법 연습 - 1

o_jooon_·약 23시간 전
0

pandas

목록 보기
1/1
post-thumbnail

pandas에 대해 공부하면서, 기본 문법부터 알아두는게 필수이기 때문에 정리하는 중입니다.
pandas 10분 완성이라는 기초 가이드 페이지가 있어, 이를 보고 따라해보며 문법을 익히고 정리하는 포스팅입니다.

내용이 생각보다 길어서, 2번 또는 3번에 나눠서 포스팅 할 예정입니다.
가이드에서 나온 설명에는 부족한 점이 있어서 추가 내용을 포함하여 정리중입니다.

Jupyter lab, VsCode를 통한 ipynb 파일 기준으로 작성했습니다.


목차

  1. Object Creation (객체 생성)
  2. Viewing Data (데이터 확인하기)
  3. Selection (선택)

먼저, 필요한 패키지를 설치해줍니다.
pandas, numpy, matplotlib를 설치하는데, import 전에 pip install을 통해 설치해주어야 합니다.
VSCode에서 터미널을 통해 설치해 줄 수 있습니다.

$ pip install pandas
$ pip install numpy
$ pip install matplotlib

설치가 완료되었으면 패키지를 불러옵니다.
일반적으로 각 패키지는 pd, np, plt라는 이름으로 불러옵니다.

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt

1. Object Creation (객체 생성)

Pandas는 값을 가지고 있는 리스트를 통해 Series를 만들고, 정수로 만들어진 인덱스를 기본값으로 불러옵니다.

s = pd.Series([1, 3, 5, np.nan, 6, 8])
s

Output:

0    1.0
1    3.0
2    5.0
3    NaN
4    6.0
5    8.0
dtype: float64
  • Series: pandas에서 사용하는 1차원 데이터 구조입니다. 배열처럼 사용되며, 인덱스를 가집니다.
    DataFrame의 한 열(column)이라고 보시면 되겠습니다.
  • np.nan: NaN 값, 즉 값이 없는 결측 데이터입니다.
  • dtype: 데이터 타입(data type) 입니다. int64, float64, bool, datetime64 등이 있습니다.

datatime 인덱스와 레이블(Label)이 있는 column을 가지고 있는 numpy 배열을 전달하여 데이터프레임을 생성합니다.

dates = pd.date_range('20250123', periods=6)
dates

Output:

DatetimeIndex(['2025-01-23', '2025-01-24', '2025-01-25', '2025-01-26',
               '2025-01-27', '2025-01-28'],
              dtype='datetime64[ns]', freq='D')
  • periods를 설정하면, 입력한 날짜부터 n일차 까지의 날짜를 차례대로 생성합니다.

df = pd.DataFrame(np.random.randn(6, 4), index=dates, columns=list('ABCD'))
df

Output:

                   A         B         C         D
2025-01-23  0.470623 -1.544299 -0.359713  0.341314
2025-01-24 -0.989620 -0.296540  0.083644 -1.485904
2025-01-25  0.602569 -0.716880  0.785357  0.572783
2025-01-26 -0.621514 -0.318548 -1.075782  2.061741
2025-01-27 -1.626353 -1.416525 -0.516248 -1.631344
2025-01-28 -0.817248  1.168349 -0.803450 -1.352421
  • 각 row의 인덱스를 날짜 순서대로, column은 A, B, C, D로 하는 DataFrame을 생성합니다.
  • np.random.randn(row, column): 행(row)과 열(column)의 개수만큼 행렬을 생성하며, 각 칸마다 정규분포에서 난수를 생성합니다. 대부분 -3에서 3사이의 값입니다.

Series와 같은 것으로 변환될 수 있는 객체들의 dictionary로 구성된 데이터프레임을 만듭니다.
각 Key는 column을, Value는 칸에 맞는 값이 할당됩니다. row는 기본 인덱스로 지정이되며, 따로 설정해주고 싶은 경우는 pd.DataFrame.from_dict() 등을 통해 가능하다고 하네요.

df2 = pd.DataFrame({
    'A': 1.,
    'B': pd.Timestamp('20250123'),
    'C': pd.Series(1, index=list(range(4)), dtype='float32'),
    'D': np.array([3] * 4, dtype='int32'),
    'E': pd.Categorical(["test", "traing", "test", "traint"]),
    'F': 'foo'
})
df2

Output:

     A          B    C  D       E    F
0  1.0 2025-01-23  1.0  3    test  foo
1  1.0 2025-01-23  1.0  3  traing  foo
2  1.0 2025-01-23  1.0  3    test  foo
3  1.0 2025-01-23  1.0  3  traint  foo
  • pd.Timestamp: 날짜와 시간 정보를 포함하는 객체입니다.
  • pd.Categorical: 메모리 최적화를 위해 유한한 범주의 값을 나타내는 객체입니다.
    보통 문자열이나 정수로 표현하고, 데이터를 압축하기 때문에 메모리 사용량을 줄여 대규모 데이터에 유리하다고 합니다.

DataFrame의 결과물의 column은 다양한 데이터 타입(dtpyes)으로 구성됩니다.

df2.dtypes

Output:

A          float64
B    datetime64[s]
C          float32
D            int32
E         category
F           object
dtype: object

2. Viewing Data (데이터 확인하기)

DataFrame의 가장 윗 줄과 마지막 줄을 확인하고 싶을 때에 사용하는 방법은 다음과 같습니다.

  • 괄호 안에는 숫자가 들어갈 수도 있고 안 들어갈 수도 있습니다.
  • 숫자가 들어간다면, 윗 / 마지막 줄의 특정 줄을 불러올 수 있습니다.
  • 숫자가 들어가지 않는다면, 기본값은 5로 처리됩니다.
df.tail(3) # 끝에서 마지막 3줄
df.tail() # 끝에서 마지막 5줄

Output:

                   A         B         C         D
2025-01-24 -0.989620 -0.296540  0.083644 -1.485904
2025-01-25  0.602569 -0.716880  0.785357  0.572783
2025-01-26 -0.621514 -0.318548 -1.075782  2.061741
2025-01-27 -1.626353 -1.416525 -0.516248 -1.631344
2025-01-28 -0.817248  1.168349 -0.803450 -1.352421
  • 해당 Output은 둘째 줄 코드인 df.tail()의 결과로, 뒤에서부터 5개의 row를 불러옵니다.

df.head() # 처음에서 5줄

Output:

                   A         B         C         D
2025-01-23  0.470623 -1.544299 -0.359713  0.341314
2025-01-24 -0.989620 -0.296540  0.083644 -1.485904
2025-01-25  0.602569 -0.716880  0.785357  0.572783
2025-01-26 -0.621514 -0.318548 -1.075782  2.061741
2025-01-27 -1.626353 -1.416525 -0.516248 -1.631344
  • 위에서부터 5개의 row를 불러옵니다.

df.tail(3)

Output:

                   A         B         C         D
2025-01-26 -0.621514 -0.318548 -1.075782  2.061741
2025-01-27 -1.626353 -1.416525 -0.516248 -1.631344
2025-01-28 -0.817248  1.168349 -0.803450 -1.352421
  • 뒤에서부터 3개의 row를 불러옵니다.

인덱스 (index), 열 (column) 그리고 numpy 데이터에 대한 세부 정보를 봅니다.

df.index

Output:

DatetimeIndex(['2025-01-23', '2025-01-24', '2025-01-25', '2025-01-26',
               '2025-01-27', '2025-01-28'],
              dtype='datetime64[ns]', freq='D')
  • index를 통해 각 row를 구분하는 인덱스의 배열을 불러올 수 있습니다.
  • freq: DatatimeIndex가 있는 경우 출력되는 시간 주기(frequency) 입니다.
    뒤에 붙는 문자열은 다음과 같습니다.
    - D: 일 단위 (Daily)
    - W: 주 단위 (Weekly)
    - M: 월 단위 (Month-End)
    - Q: 분기 단위 (Quarter-End)
    - Y or A: 연 단위 (Year-End)
    - H: 시간 단위 (Hourly)
    - T: or min 분 단위 (Minute)
    - S: 초 단위 (Second)

df.columns

Output:

Index(['A', 'B', 'C', 'D'], dtype='object')
  • colums를 통해 column의 배열을 불러올 수 있습니다.

df.values

Output:

array([[ 0.47062305, -1.54429928, -0.3597129 ,  0.34131384],
       [-0.98961962, -0.29653974,  0.08364368, -1.48590371],
       [ 0.60256886, -0.71687987,  0.78535709,  0.57278294],
       [-0.62151395, -0.31854779, -1.0757822 ,  2.06174073],
       [-1.62635282, -1.41652459, -0.51624819, -1.63134446],
       [-0.81724815,  1.16834876, -0.80344996, -1.35242074]])
  • values를 통해 DataFrame의 모든 값을 2차원 배열의 형태로 불러올 수 있습니다.

describe()는 데이터의 대략적인 통계적 정보 요약을 보여줍니다.

df.describe()

Output:

              A         B         C         D
count  6.000000  6.000000  6.000000  6.000000
mean  -0.496924 -0.520740 -0.314365 -0.248972
std    0.869657  0.983132  0.667768  1.484700
min   -1.626353 -1.544299 -1.075782 -1.631344
25%   -0.946527 -1.241613 -0.731650 -1.452533
50%   -0.719381 -0.517714 -0.437981 -0.505553
75%    0.197589 -0.302042 -0.027195  0.514916
max    0.602569  1.168349  0.785357  2.061741
  • count: column의 유효값(결측값이 아닌 값)의 개수
  • mean: column의 평균값
  • std: column의 표준편차 (데이터의 분산 정도)
  • min: column의 최솟값
  • 25%: column의 1사분위수 (데이터의 하위 25% 지점)
  • 50%: column의 중앙값 (데이터의 50% 지점, 2사분위수 또는 중위수)
  • 75%: column의 3사분위수 (데이터의 상위 25%를 제외한 하위 75% 지점)
  • max: column의 최댓값

데이터를 전치합니다.

df.T

Output:

   2025-01-23  2025-01-24  2025-01-25  2025-01-26  2025-01-27  2025-01-28
A    0.470623   -0.989620    0.602569   -0.621514   -1.626353   -0.817248
B   -1.544299   -0.296540   -0.716880   -0.318548   -1.416525    1.168349
C   -0.359713    0.083644    0.785357   -1.075782   -0.516248   -0.803450
D    0.341314   -1.485904    0.572783    2.061741   -1.631344   -1.352421
  • row와 column이 뒤집힌 것을 볼 수 있습니다.

sort_index()에서 axis = 0인 경우 행(row)을 기준으로 정렬하고, axis = 1인 경우 열(column)을 기준으로 정렬합니다.

df.sort_index(axis=1, ascending=False)

Output:

                   D         C         B         A
2025-01-23  0.341314 -0.359713 -1.544299  0.470623
2025-01-24 -1.485904  0.083644 -0.296540 -0.989620
2025-01-25  0.572783  0.785357 -0.716880  0.602569
2025-01-26  2.061741 -1.075782 -0.318548 -0.621514
2025-01-27 -1.631344 -0.516248 -1.416525 -1.626353
2025-01-28 -1.352421 -0.803450  1.168349 -0.817248
  • ascending: 정렬 기준을 나타냅니다. False는 내림차순, True는 오름차순을 기준으로 정렬합니다.
    default 값은 False 입니다.
  • 해당 결과는 column을 내림차순으로 정렬했으므로, 알파벳이 큰 D부터 작은 A까지 정렬되었습니다.

값 별로 정렬합니다.

df.sort_values(by='B')

Output:

                   A         B         C         D
2025-01-23  0.470623 -1.544299 -0.359713  0.341314
2025-01-27 -1.626353 -1.416525 -0.516248 -1.631344
2025-01-25  0.602569 -0.716880  0.785357  0.572783
2025-01-26 -0.621514 -0.318548 -1.075782  2.061741
2025-01-24 -0.989620 -0.296540  0.083644 -1.485904
2025-01-28 -0.817248  1.168349 -0.803450 -1.352421
  • B를 기준으로 각 row를 내림차순 합니다.

3. Selection (선택)

Python 및 Numpy의 선택과 설정을 위한 표현들은 직관적이고 코드 작성을 위한 작업에 유용합니다.
.at, .iat, .loc, .iloc가 pandas에 최적화되어 있기 때문에 사용하는 것을 추천한다고 합니다.

Getting (데이터 얻기)

df.A와 동일한 Series를 생성하는 단일 column을 선택합니다.

df['A']

Output:

2025-01-23    0.470623
2025-01-24   -0.989620
2025-01-25    0.602569
2025-01-26   -0.621514
2025-01-27   -1.626353
2025-01-28   -0.817248
Freq: D, Name: A, dtype: float64
  • 해당 결과의 데이터 구조는 Series 입니다.

슬라이싱을 통해 row를 선택할 수 있습니다.

df[0:3]

Output:

                   A         B         C         D
2025-01-23  0.470623 -1.544299 -0.359713  0.341314
2025-01-24 -0.989620 -0.296540  0.083644 -1.485904
2025-01-25  0.602569 -0.716880  0.785357  0.572783
  • 0번째 인덱스('20250123')부터 2번째 인덱스('20250125')까지의 row를 불러옵니다.

df['20250123':'20250125']

Output:

                   A         B         C         D
2025-01-23  0.470623 -1.544299 -0.359713  0.341314
2025-01-24 -0.989620 -0.296540  0.083644 -1.485904
2025-01-25  0.602569 -0.716880  0.785357  0.572783
  • 직접 입력한 범위의 row를 불러옵니다. 숫자 인덱스와는 다르게 뒤의 범위를 포함합니다.

Selection by Label (Label을 통한 선택)

Label을 사용하여 횡단면을 얻습니다.

df.loc[dates[0]]

Output:

A    0.470623
B   -1.544299
C   -0.359713
D    0.341314
Name: 2025-01-23 00:00:00, dtype: float64
  • 결과의 데이터 구조는 Series 입니다.
  • 0번째 인덱스('20250123')의 각 column에 대한 정보입니다.
  • loc: Label을 기준으로 데이터를 불러옵니다.

Label을 사용하여 여러 축의 데이터를 얻습니다.

df.loc[:, ['A', 'B']]

Output:

                   A         B
2025-01-23  0.470623 -1.544299
2025-01-24 -0.989620 -0.296540
2025-01-25  0.602569 -0.716880
2025-01-26 -0.621514 -0.318548
2025-01-27 -1.626353 -1.416525
2025-01-28 -0.817248  1.168349
  • 결과의 데이터 구조는 DataFrame 입니다.
  • loc에서는 콤마(,)를 기준으로 row, column을 나타내는데 :모든 행을, ['A', 'B']'A'와 'B' column을 나타냅니다.
  • 이렇게 row와 column의 범위를 모두 지정해주면 2차원 데이터 구조인 DataFrame을, 하나만 지정하면 1차원 데이터 구조인 Series 타입의 결과를 얻게됩니다.
    (범위를 지정해야 2차원이고, 값 하나만 지정하면 1차원입니다. 아래와 비교하면 이해하기 편합니다.)

양쪽 종단점을 포함한 Label 슬라이싱을 불러옵니다.

df.loc['20250123':'20250125', ['A','B']]

Output:

                   A         B
2025-01-23  0.470623 -1.544299
2025-01-24 -0.989620 -0.296540
2025-01-25  0.602569 -0.716880
  • row와 column를 지정한 만큼 불러옵니다.

반환되는 객체의 차원을 줄입니다.

df.loc['20250123', ['A','B']]

Output:

A    0.470623
B   -1.544299
Name: 2025-01-23 00:00:00, dtype: float64
  • 하나의 row에 대한 결과를 불러오기 때문에, Series 타입입니다.

스칼라 값을 얻습니다.

df.loc[dates[0], 'A']

Output:

0.47062305067298715
  • dates[0]에 해당하는 인덱스(row)와 A에 해당하는 column이 교차하는 지점의 위치에 대한 스칼라 값입니다.
    이 값을 통해 무엇을 하는지는 아직 잘 모르겠습니다.. 나중에 쓸 일이 있으면 추가하겠습니다!

스칼라 값을 더 빠르게 구하는 방법입니다.

df.at[dates[0], 'A']

Output:

0.47062305067298715
  • at: 단일 값인 스칼라값에만 접근합니다. loc여러 개의 값을 선택할 수 있지만 at하나의 값만 선택하기 때문에 스칼라 값을 구하는 경우에 더 빠릅니다.

Selection by Position (위치로 선택하기)

넘겨받은 정수의 위치(인덱스)를 기준으로 선택합니다.
loc가 인덱스의 특정 값을 통해 범위를 지정했다면, iloc는 인덱스 위치(배열의 0번째 인덱스와 같이)로 접근합니다.

df.iloc[3]

Output:

A   -0.621514
B   -0.318548
C   -1.075782
D    2.061741
Name: 2025-01-26 00:00:00, dtype: float64
  • 인덱스의 3번째 값인 20250126에 대한 Series 데이터입니다.

정수로 표기된 슬라이스들을 통해, Python/Numpy와 유사하게 작동합니다.

df.iloc[3:5, 0:2]

Output:

                   A         B
2025-01-26 -0.621514 -0.318548
2025-01-27 -1.626353 -1.416525
  • row의 3번째 인덱스부터 4번째 인덱스, column의 0번째 인덱스부터 1번째 인덱스까지의 DataFrame 데이터입니다.

정수로 표기된 위치값의 리스트들을 통해, Python/Numpy의 스타일과 유사해집니다.

df.iloc[[1,2,4],[0,2]]

Output:

                   A         C
2025-01-24 -0.989620  0.083644
2025-01-25  0.602569  0.785357
2025-01-27 -1.626353 -0.516248
  • 범위가 아닌 특정 row의 인덱스 위치를 리스트에 담아 불러올 수 있습니다.

명시적으로 행을 나누고자 하는 경우입니다.

df.iloc[1:3,:]

Output:

                   A        B         C         D
2025-01-24 -0.989620 -0.29654  0.083644 -1.485904
2025-01-25  0.602569 -0.71688  0.785357  0.572783
  • row의 1번째 인덱스부터 2번째 인덱스, 모든 column의 DataFrame 데이터입니다.

명시적으로 열을 나누고자 하는 경우입니다.

df.iloc[:,1:3]

Output:

                   B         C
2025-01-23 -1.544299 -0.359713
2025-01-24 -0.296540  0.083644
2025-01-25 -0.716880  0.785357
2025-01-26 -0.318548 -1.075782
2025-01-27 -1.416525 -0.516248
2025-01-28  1.168349 -0.803450
  • 위와 동일하며, 범위만 다릅니다.

명시적으로 (특정한) 값을 얻고자 하는 경우입니다.

df.iloc[1,1]

Output:

-0.29653974092309904
  • [20250124, B]에 대한 스칼라 값입니다.

스칼라 값을 빠르게 얻는 방법 입니다. (위와 동일)

df.iat[1,1]

Output:

-0.29653974092309904
  • loc, at에서의 차이와 같습니다.

Boolean Indexing

데이터를 선택하기 위해 단일 열의 값을 사용합니다.

df[df.A > 0]

Output:

                   A         B         C         D
2025-01-23  0.470623 -1.544299 -0.359713  0.341314
2025-01-25  0.602569 -0.716880  0.785357  0.572783
  • A0보다 큰 데이터만 필터링한 데이터입니다.

Boolean 조건을 충족하는 DataFrame에서 값을 선택합니다.

df[df > 0]

Output:

                   A         B         C         D
2025-01-23  0.470623       NaN       NaN  0.341314
2025-01-24       NaN       NaN  0.083644       NaN
2025-01-25  0.602569       NaN  0.785357  0.572783
2025-01-26       NaN       NaN       NaN  2.061741
2025-01-27       NaN       NaN       NaN       NaN
2025-01-28       NaN  1.168349       NaN       NaN
  • 모든 데이터 중, 0보다 큰 경우에만 을 표시하고, 아닌 경우NaN을 표시합니다.

필터링을 위한 메소드 isin()을 사용합니다.

df2 = df.copy()
df2['E'] = ['one', 'one', 'two', 'three', 'four', 'three']
df2

Output:

                   A         B         C         D      E
2025-01-23  0.470623 -1.544299 -0.359713  0.341314    one
2025-01-24 -0.989620 -0.296540  0.083644 -1.485904    one
2025-01-25  0.602569 -0.716880  0.785357  0.572783    two
2025-01-26 -0.621514 -0.318548 -1.075782  2.061741  three
2025-01-27 -1.626353 -1.416525 -0.516248 -1.631344   four
2025-01-28 -0.817248  1.168349 -0.803450 -1.352421  three
  • 지정한 데이터가 들어있는 column E를 추가합니다.

df2[df2['E'].isin(['two', 'four'])]

Output:

                   A         B         C         D     E
2025-01-25  0.602569 -0.716880  0.785357  0.572783   two
2025-01-27 -1.626353 -1.416525 -0.516248 -1.631344  four
  • E column 중, 값이 twofour인 데이터의 row를 불러옵니다.

Setting (설정)

새 column을 설정하면 데이터가 인덱스 별로 자동 정렬됩니다.

s1 = pd.Series([1, 2, 3, 4, 5, 6], index = pd.date_range('20250123', periods=6))
s1

Output:

2025-01-23    1
2025-01-24    2
2025-01-25    3
2025-01-26    4
2025-01-27    5
2025-01-28    6
Freq: D, dtype: int64
  • 새로운 데이터를 가진 column을 생성합니다.

위에서 생성한 데이터를 F라는 column에 넣어 추가합니다.

df['F'] = s1

Label에 의해 값을 설정합니다.

df.at[dates[0], 'A'] = 0
  • [20250123, A]의 값을 0으로 바꿉니다.

위치에 의해 값을 설정합니다.

df.iat[0, 1] = 0
  • [20250123, B]의 값을 0으로 바꿉니다.

Numpy 배열을 사용한 할당에 의해 값을 설정합니다.

df.loc[:, 'D'] = np.array([5] * len(df))
  • D column의 모든 값을 5로 바꿉니다.

위 설정대로 작동한 결과입니다.

df

Output:

                   A         B         C    D  F
2025-01-23  0.000000  0.000000 -0.359713  5.0  1
2025-01-24 -0.989620 -0.296540  0.083644  5.0  2
2025-01-25  0.602569 -0.716880  0.785357  5.0  3
2025-01-26 -0.621514 -0.318548 -1.075782  5.0  4
2025-01-27 -1.626353 -1.416525 -0.516248  5.0  5
2025-01-28 -0.817248  1.168349 -0.803450  5.0  6
  • 정상적으로 바뀌었습니다.

where 연산을 설정한다.

df2 = df.copy()
df2[df2 > 0] = -df2
  • 값이 0보다 큰 데이터를 음수로 바꿉니다.
df2

Output:

                   A         B         C    D  F
2025-01-23  0.000000  0.000000 -0.359713 -5.0 -1
2025-01-24 -0.989620 -0.296540 -0.083644 -5.0 -2
2025-01-25 -0.602569 -0.716880 -0.785357 -5.0 -3
2025-01-26 -0.621514 -0.318548 -1.075782 -5.0 -4
2025-01-27 -1.626353 -1.416525 -0.516248 -5.0 -5
2025-01-28 -0.817248 -1.168349 -0.803450 -5.0 -6

이번 포스팅에서는 3번째 목차까지 다루었습니다. 다음 포스팅에서는 아마 6번째나 7번째 목차까지 다룰 것 같네요.
at, iat, loc, iloc가 헷갈렸었는데, 이번 공부를 통해 많이 이해하게 되었습니다!
페이지의 제목은 pandas 10분 다루기인데, 10시간으로 바꿔야하는게 아닌가 생각이되네요..

profile
안녕하세요.

0개의 댓글