본문 바로가기
스터디/데이터사이언스

[pandas] [판다스] DataFrame 조작하기, MultiIndex

by 궁금한 준이 2023. 2. 15.
728x90
반응형

전에 만든 미국 5개주의 인구와 면적 데이터를 이용해보자.

 

Transpose

DataFrame은 2차원 배열로 취급하므로 전치행렬과 같은 transpose 연산이 가능하다. 

population_dict = {
    'California': 38332521,
    'Texas': 26448193,
    'New York': 19651127,
    'Florida': 19552860,
    'Illinois': 12882135,
}

area_dict = {
    'California': 423967, 
    'Texas': 695662, 
    'New York': 141297,
    'Florida': 170312, 
    'Illinois': 149995,
}

states_T = pd.DataFrame([population_dict, area_dict],
                       index=['population', 'area'])

states_T
states = states_T.T
states

states_T
states

Adding a column

기존의 컬럼들을 이용하여 새로운 컬럼 데이터를 생성할 수 있다. 생성된 컬럼은 보통 맨 오른쪽에 위치한다.

states['density'] = states['population'] / states['area']

인구밀도 density column이 추가된 states

Compare the slicing

explicit index와 implicit index(명시적/암묵적 인덱싱)이 가능하다.

explicit index를 하면 last index가 포함되고, implicit indexing을 사용하면 일반적인 파이썬 인덱싱처럼 last index는 포함되지 않는다. 

loc는 항상 explicit indexing을, iloc는 항상 implicit indexing을 사용한다.

states['California': 'Florida'] # states.loc['California': 'Florida']
states[1:3] # states.iloc[1:3]

 

Filtering

DataFrame 속 데이터 값이 어떤 조건을 만족하는 경우만 걸러서 필터링이 필요할 때가 있다. 

states[states.density > 100]

또는 데이터가 특정 함수(e.g. 로그변환)을 통해 변환할 필요가 있다. 넘파이 함수에 그대로 DataFrame를 input으로 하여 간단히 해결할 수 있다.

np.log(states)

데이터 전체가 로그변환된다.

DataFrame Copy

https://pandas.pydata.org/docs/reference/api/pandas.DataFrame.copy.html

import copy 를 하여 copy.deepcopy(df)를 할 수도 있지만, pandas 내부에 기본적으로 copy가 메소드가 존재한다. 

default값은 deepcopy를 수행한다.

states_copy = states.copy()
states_copy['log-area'] = np.log(states_copy.area)
states_copy

states_copy

Missing data

기본적으로 missing data는 NaN으로 채워진다. 

dropna(axis=1) 메소드를 이용해서 NaN이 있는 열을 제외할 수 있다. axis=0으로 하면 row 기준으로 동작한다.

tmp = states + states_copy
tmp
tmp2 = tmp.dropna(axis=1)
tmp2

(좌) tmp는 log-area column이 NaN으로 채워진다. (우) tmp2는 NaN으로 채워진 log-area column이 drop되었다.

 

High dimensional data using MultiIndex

Series는 1d, DataFrame은 2d 데이터에 적합하다.

다른 object로 Panel은 3d, Panel4D는 4d data에 사용되지만 사용하기 쉽지 않다. 게다가 0.20 버전 이후로 deprecated되었다. 

대신에 DataFrame에 MultiIndex를 이용하여 고차원데이터를 다룰 수 있다.

 

먼저, MultiIndex를 생성해보자. 크게 array, tuple, product를 이용하여 인덱스-pair를 생성한다고 생각하면 된다.

rows = pd.MultiIndex.from_arrays([
    [2013, 2013, 2014, 2014],
    ['S', 'F', 'S', 'F']
])

rows = pd.MultiIndex.from_tuples([
    (2013, 'S'), (2013, 'F'), (2014, 'S'), (2014, 'F')
])

rows = pd.MultiIndex.from_product([
    [2013, 2014], ['S', 'F']
])

MultiIndex([(2013, 'S'),
            (2013, 'F'),
            (2014, 'S'),
            (2014, 'F')],
           )
           
rows.names = ['year', 'semester']
print(rows)

MultiIndex([(2013, 'S'),
            (2013, 'F'),
            (2014, 'S'),
            (2014, 'F')],
           names=['year', 'semester'])
​

column도 생성해보자

cols = pd.MultiIndex.from_product([
    ['Bob', 'Guido', 'Sue'], ['HR', 'Temp']
])
cols.names = ['subject', 'type']
print(cols)

MultiIndex([(  'Bob',   'HR'),
            (  'Bob', 'Temp'),
            ('Guido',   'HR'),
            ('Guido', 'Temp'),
            (  'Sue',   'HR'),
            (  'Sue', 'Temp')],
           names=['subject', 'type'])
           
           
data = np.random.randint(300, 400, size=(4, 6)) / 10
data[:, ::2] = np.round(data[:, ::2] * 2) - 10

df = pd.DataFrame(data=data, index=rows, columns=cols)
df

4D-DataFrame

groupby

groupby는 크게 3가지 단계로 구분된다. split - apply - combine

split by key - apply aggregate(sum, mean, max, ...) - combine them

data = pd.DataFrame({
    'key': ['A', 'B', 'C', 'A', 'B', 'C'],
    'data': [1, 2, 3, 4, 5, 6],
})
data.groupby(by='key').sum()
input split apply (여기서는 sum) combine (output)

 

이제 MultiIndex로 구성된 DataFrame에서도 groupby를 해보자.

df.groupby(level='semester').sum()             # (1)

df_mean = df.groupby(level='year').mean()      # (2) 
df_mean.groupby(level='subject', axis=1).min() # (3)

(1), (2), (3)

Pandas to read/write file

pandas는 여러가지 파일 포맷을 지원한다. csv, excel, HTML, txt, JSON, LaTeX, pickle 등을 지원한다. 

CSV 파일은 pd.read_csv()로 읽고, df.to_csv()로 파일을 저장한다.

EXCEL파일은 pd.read_excel()로 읽고, df.to_excel()로 파일을 저장한다. (xls만 지원)

보안상의 이슈로 인해, 1.2.0부터는 xls만 지원하고, 다른형태의 엑셀파일은 다른 engine을 설치해야한다고 한다. 대표적으로 openpyxl 패키지가 있다.

 

 

 

 

728x90
반응형