
๋ฐ์ดํฐ๋ฅผ ๋ก๋ํ์ ๋ ์ซ์๊ฐ ๋ฌธ์์ด๋ก ์ธ์๋๊ฑฐ๋, ๋ ์ง๊ฐ ๊ฐ์ฒด(Object)๋ก ์ธ์๋๋ ๊ฒฝ์ฐ ์ฌ๋ฐ๋ฅธ ํํ๋ก ๋ณํํด์ผ ์ ํํ ์ฐ์ฐ์ด ๊ฐ๋ฅํฉ๋๋ค.
astype(): ๊ฐ์ฅ ๊ธฐ๋ณธ์ ์ธ ๋ช
์์ ํ๋ณํ ๋ฉ์๋์
๋๋ค.df.astype('int32') ๋๋ df.astype({'col1': 'int32'})
# ๋ฐ์ดํฐํ๋ ์์ ์๋ฃํ ๋ณํ
# DataFrame.astype(dtype, copcy=None, errors='raise')
# ์๋ฆฌ์ฆ์ ์๋ฃํ ๋ณํ
# Series.astype(dtype, copy=None, erros='raise')
# ๋จ์ผ ์ปฌ๋ผ ๋ณํ
df['col1'] = df['col1'].astype('int32')
# ๋์
๋๋ฆฌ๋ฅผ ์ด์ฉํ ๋ค์ค ์ปฌ๋ผ ๋ณํ
df = df.astype({'col1': 'int32', 'col2': 'float64'})
# ๋ฒ์ฃผํ ๋ฐ์ดํฐ๋ก ๋ณํ (๋ฉ๋ชจ๋ฆฌ ์ ์ฝ ๋ฐ ๋ถ์ ํจ์จ์ฑ ์ฆ๋)
df['category_col'] = df['category_col'].astype('category')
to_numeric, to_datetime, to_timedelta: ํน์ ํ์
์ผ๋ก ์์ ํ๊ฒ ๋ณํํ๋ ํจ์๋ค.to_numeric: ๋ฌธ์์ด์ด ์์ฌ ์์ ๋ errors='coerce' ์ต์
์ ์ฌ์ฉํ๋ฉด ๋ณํ ๋ถ๊ฐ๋ฅํ ๊ฐ์ NaN์ผ๋ก ์ฒ๋ฆฌํ์ฌ ์์ ํ๊ฒ ์ซ์๋ก ๋ฐ๊ฟ ์ ์์ต๋๋ค.copy ํ๋ผ๋ฏธํฐ๋ ํฅํ Copy-on-Write ๋ฐฉ์์ผ๋ก ๋์ฒด๋ ์์ ์ด๋ฏ๋ก ์ฌ์ฉ์ ์ง์ํ๋ ๊ฒ์ด ์ข์ต๋๋ค.convert_dtypes(): ๊ฐ๋ฅํ ๊ฐ์ฅ ์ ์ ํ ํ์
(์: nullable int, string)์ผ๋ก ์๋ ๋ณํ์ ์๋ํฉ๋๋ค. ์ต์ Pandas์์ ๊ถ์ฅํ๋ ๋ฐฉ์ ์ค ํ๋์
๋๋ค.df.isna() ๋๋ df.isnull()dropna):df.dropna(axis=0): ๊ฒฐ์ธก์น๊ฐ ์๋ ํ ์ญ์ .df.dropna(how='all'): ๋ชจ๋ ๊ฐ์ด ๊ฒฐ์ธก์น์ธ ๊ฒฝ์ฐ๋ง ์ญ์ .df.dropna(thresh=N): ์ ์ ๋ฐ์ดํฐ๊ฐ N๊ฐ ์ด์์ด๋ฉด ์ ์ง.fillna):df.fillna(0): 0์ผ๋ก ์ฑ์.df.fillna(df.mean()): ํ๊ท ๊ฐ์ผ๋ก ๋์ฒด.ffill()(์์ ๊ฐ์ผ๋ก ์ฑ์), bfill()(๋ค์ ๊ฐ์ผ๋ก ์ฑ์).df.drop_duplicates(subset=['col1', 'col2'], keep='first'): ํน์ ์ปฌ๋ผ ๊ธฐ์ค ์ค๋ณต ์ ๊ฑฐ.๋ฐ์ดํฐ๋ฅผ ํน์ ๊ธฐ์ค์ ๋ฐ๋ผ ๋๋๊ณ (Split), ๊ฐ ๊ทธ๋ฃน์ ์ฐ์ฐ์ ์ ์ฉํ๊ณ (Apply), ๊ฒฐ๊ณผ๋ฅผ ๋ค์ ํฉ์น๋(Combine) ๊ฐ๋ ฅํ ๊ณผ์ ์ ๋๋ค.
groupby())# ๋ฐ์ดํฐํ๋ ์ ๊ฐ์ฒด ์์ฑ
# DataFrame.groupby(by=None, axis=<no_default> , level=None, as_index=True,
# sort=True, group_keys=True, observed=<no_default> , dropna=True)
grouped = df.groupby('Key_Column')
# ์ฌ๋ฌ ์ปฌ๋ผ ๊ธฐ์ค
grouped = df.groupby(['Key1', 'Key2'])
Split ๋จ๊ณ๋ ๋ฐ์ดํฐ๋ฅผ ํน์ ๊ธฐ์ค(Key)์ ๋ฐ๋ผ ๋ ผ๋ฆฌ์ ์ผ๋ก ๋๋๋ ๊ณผ์ ์ ๋๋ค. ์ด ๋จ๊ณ์์ ์ฆ์ ๊ณ์ฐ์ด ์ํ๋๋ ๊ฒ์ ์๋๋ฉฐ, GroupBy ๊ฐ์ฒด(์ค๊ฐ์ฒด) ๊ฐ ์์ฑ๋ฉ๋๋ค.
by ํ๋ผ๋ฏธํฐ)Pandas๋ ๋งค์ฐ ์ ์ฐํ ๋ถํ ๊ธฐ์ค์ ์ ๊ณตํฉ๋๋ค.
# 'School' ์ปฌ๋ผ์ ๊ฐ(์: A๊ณ ๊ต, B๊ณ ๊ต)์ ๊ธฐ์ค์ผ๋ก ๋๋
grouped = df.groupby('School')# 'School'๋ก ๋จผ์ ๋๋๊ณ , ๊ทธ ์์์ 'Grade'๋ก ๋ค์ ๋๋
grouped = df.groupby(['School', 'Grade'])# ์ธ๋ฑ์ค๊ฐ ๋ ์ง์ผ ๋, ์ฐ๋(year)๋ณ๋ก ๊ทธ๋ฃนํ
df.groupby(lambda x: x.year)
# ๋์
๋๋ฆฌ๋ก ์ธ๋ฑ์ค ๋งคํ (a, b๋ 'First', c๋ 'Second' ๊ทธ๋ฃน)
mapping = {'a': 'First', 'b': 'First', 'c': 'Second'}
df.groupby(mapping)GroupBy ๊ฐ์ฒด๋ ๊ฒ์ผ๋ก ๋ณด๊ธฐ์ ์๋ฌด๊ฒ๋ ์ ๋ณด์ด์ง๋ง, ๋ด๋ถ์ ์ผ๋ก๋ ๊ทธ๋ฃน ์ ๋ณด๋ฅผ ๊ฐ์ง๊ณ ์์ต๋๋ค. ์ด๋ฅผ ํ์ธํ๋ ๋ฐฉ๋ฒ๋ค์ ๋๋ค.
groups ์์ฑ: ๊ฐ ๊ทธ๋ฃน์ ์ด๋ฆ(Key)๊ณผ ํด๋น ๋ฐ์ดํฐ์ ์ธ๋ฑ์ค(Label)๋ฅผ ๋์
๋๋ฆฌ ํํ๋ก ๋ณด์ฌ์ค๋๋ค.print(grouped.groups)
# ๊ฒฐ๊ณผ: {'A๊ณ ๊ต': [0, 2, 5], 'B๊ณ ๊ต': [1, 3, 4]}get_group() ๋ฉ์๋: ํน์ ๊ทธ๋ฃน์ ๋ฐ์ดํฐ๋ง DataFrame์ผ๋ก ์ถ์ถํด ๋ด
๋๋ค. (๋๋ฒ๊น
ํ ๋ ์ ์ฉ)# 'A๊ณ ๊ต' ๊ทธ๋ฃน์ ์ํ ๋ฐ์ดํฐ๋ง ํ์ธ
a_school_data = grouped.get_group('A๊ณ ๊ต')(๊ทธ๋ฃน๋ช
, ๋ฐ์ดํฐํ๋ ์) ์์ ์ํํ ์ ์์ต๋๋ค.for name, group_df in grouped:
print(f"Group Name: {name}")
print(group_df.head()) # ๊ฐ ๊ทธ๋ฃน์ ๋ฐ์ดํฐ ์ถ๋ ฅgroupby()๋ง ์คํํ์ ๋๋ ์ค์ ํต๊ณ ์ฐ์ฐ(ํ๊ท , ํฉ๊ณ ๋ฑ)์ ์ํํ์ง ์์ต๋๋ค. sum(), mean() ๊ฐ์ Apply ๋จ๊ณ์ ํจ์๊ฐ ํธ์ถ๋ ๋ ๋น๋ก์ ์ฐ์ฐ์ด ์์๋ฉ๋๋ค.NaN(๊ฒฐ์ธก์น)์ด ํฌํจ๋์ด ์์ผ๋ฉด, ํด๋น ํ์ ๊ทธ๋ฃน์์ ์ ์ธ๋ฉ๋๋ค. (์ต์
dropna=False๋ฅผ ์ฃผ๋ฉด NaN๋ ํ๋์ ๊ทธ๋ฃน์ผ๋ก ์ธ์ ํฉ๋๋ค.)๊ทธ๋ฃน๋ณ๋ก ๋ฐ์ดํฐ๋ฅผ ์์ฝํ์ฌ ํ๋์ ์ค์นผ๋ผ ๊ฐ์ ๋ง๋ญ๋๋ค. ๊ฒฐ๊ณผ ๋ฐ์ดํฐ์ ํฌ๊ธฐ๊ฐ ์ค์ด๋ญ๋๋ค.
sum(), mean(), std(), min(), max(), size()agg() ์ฌ์ฉ: ์ฌ๋ฌ ํจ์๋ฅผ ๋์์ ์ ์ฉํ๊ฑฐ๋ ์ปฌ๋ผ๋ณ๋ก ๋ค๋ฅธ ํจ์๋ฅผ ์ ์ฉํ ๋ ์ ์ฉํฉ๋๋ค.# ์ปฌ๋ผ๋ณ ๋ค๋ฅธ ์ฐ์ฐ ์ ์ฉ
df.groupby("kind").agg(
min_height=("height", "min"),
avg_weight=("weight", "mean")
)๊ทธ๋ฃน๋ณ๋ก ๊ฐ์ ๋ณ๊ฒฝํ๊ฑฐ๋ ์ ๊ทํ (cumsum, diff ๋ฑ)๋ฅผ ์ํํ๋, ๊ฒฐ๊ณผ ๋ฐ์ดํฐ์ ํฌ๊ธฐ๊ฐ ์๋ณธ๊ณผ ๋์ผํ๊ฒ ์ ์ง๋ฉ๋๋ค. ๊ฐ ํ์ ๊ทธ๋ฃน๋ณ ํน์ฑ์ ๋ฐ์ํ ๋ ์ฌ์ฉํฉ๋๋ค.
# ๊ฐ ๊ทธ๋ฃน์ ํ์คํธ์ฐจ๋ก ๋๋๊ธฐ (Standardization)
df.groupby('A').transform(lambda x: (x - x.mean()) / x.std())
# ๊ฐ ๊ทธ๋ฃน ๋ด์์ ๋์ ํฉ ๊ณ์ฐ
grouped.cumsum()์กฐ๊ฑด์ ๋ง์กฑํ์ง ์๋ ๊ทธ๋ฃน ์ ์ฒด๋ฅผ ์ญ์ ํฉ๋๋ค. (loc ๋ฑ์ ์ด์ฉํ ํ ๋จ์ ํํฐ๋ง๊ณผ๋ ๋ค๋ฆ
๋๋ค.)
# ๊ทธ๋ฃน ๋ด ๋ฐ์ดํฐ ๊ฐ์(len)๊ฐ 2๋ณด๋ค ํฐ ๊ทธ๋ฃน๋ง ๋จ๊น
df.groupby("B").filter(lambda x: len(x) > 2)๊ฐ์ฅ ์ผ๋ฐ์ ์ธ ํํ์ ๋๋ค. ์์์ ํจ์๋ฅผ ์ ์ฉํ ์ ์์ผ๋ฉฐ, ๊ฒฐ๊ณผ ํํ๊ฐ ์ ๋์ ์ ๋๋ค. ๋ค๋ง, ์๋๊ฐ ๋๋ฆด ์ ์์ต๋๋ค.
# DataFrameGroupBy.apply(func, *args, include_groups=True, **kwargs)
include_groups=False๋ฅผ ์ง์ ํ์ฌ ๊ทธ๋ฃนํ ํค๊ฐ ๊ฒฐ๊ณผ์ ์ค๋ณต ํฌํจ๋๋ ๊ฒ์ ๋ฐฉ์งํ๋ ๊ฒ์ด ์ข์ต๋๋ค.๋ฐ์ดํฐ์ ํํ๋ฅผ ๋ถ์ ๋ชฉ์ ์ ๋ง๊ฒ ๋ณ๊ฒฝํ๋ ๊ธฐ๋ฅ๋ค์ ๋๋ค.
pivot: ๋ฐ์ดํฐ์ ํน์ ์ปฌ๋ผ ๊ฐ์ ์๋ก์ด ์ปฌ๋ผ ํค๋๋ก ๋ง๋ค์ด ๋ฐ์ดํฐ๋ฅผ ์์ฝ/์ฌ๋ฐฐ์นํฉ๋๋ค. ์ธ๋ก๋ก ๊ธด ๋ฐ์ดํฐ๋ฅผ ๊ฐ๋ก๋ก ๋๊ฒ ํผ์นฉ๋๋ค. (Long to Wide)์ฌ์ฉ์ฒ: ์์ฝํ ์์ฑ, ์๊ณ์ด ๋ฐ์ดํฐ ์ ๋ฆฌ.
์ฃผ์: ์ค๋ณต๋ ์ธ๋ฑ์ค/์ปฌ๋ผ ์์ด ์์ผ๋ฉด ์๋ฌ๊ฐ ๋ฐ์ํฉ๋๋ค. ์ด ๊ฒฝ์ฐ ์ง๊ณ ๊ธฐ๋ฅ์ด ํฌํจ๋ pivot_table()์ ์ฌ์ฉํด์ผ ํฉ๋๋ค.
# DataFrame.pivot(*, columns, index=<no_default>, values=<no_default>)
df.pivot(index='date', columns='variable', values='value')
melt: ์ฌ๋ฌ ์ปฌ๋ผ์ ํ๋์ ์ปฌ๋ผ์ผ๋ก ๋
น์ฌ์ ํ์ผ๋ก ๋ง๋ญ๋๋ค. ๊ฐ๋ก๋ก ๋์ ๋ฐ์ดํฐ๋ฅผ ์ธ๋ก๋ก ๊ธธ๊ฒ ๋
น์
๋๋ค. ์ปดํจํฐ๊ฐ ์ฒ๋ฆฌํ๊ธฐ ์ข์ ํํ(Tidy Data)๋ก ๋ฐ๊ฟ ๋ ์๋๋ค. (Wide to Long)id_vars: ๊ธฐ์ค์ด ๋ (์ ์งํ ) ์ปฌ๋ผ.
value_vars: ๋
น์ฌ์ ํ์ผ๋ก ๋ง๋ค ์ปฌ๋ผ.
# DataFrame.melt(id_vars=None, value_vars=None, var_name=None,
# value_name='value', col_level=None, ignore_index=True)
stack: ์ปฌ๋ผ(์ด) ๋ ๋ฒจ์ ์ธ๋ฑ์ค(ํ) ๋ ๋ฒจ๋ก ์์ถํฉ๋๋ค. (Columns Index)unstack: ์ธ๋ฑ์ค(ํ) ๋ ๋ฒจ์ ์ปฌ๋ผ(์ด) ๋ ๋ฒจ๋ก ํผ์นฉ๋๋ค. (Index Columns)groupby ํ unstack()์ ์์ฃผ ์ฌ์ฉํฉ๋๋ค.# DataFrame.stack(level=-1, dropna=<no_default>, sort=<no_default>, futures_tack=False)
# DataFrame.unstack(level=-1, fill_value=None, sort=True)
explode: ๋ฆฌ์คํธ๋ ๋ฐฐ์ด ํํ์ ๊ฐ์ ๊ฐ์ง ์ปฌ๋ผ์ ์ฌ๋ฌ ํ์ผ๋ก ๋ถ๋ฆฌํฉ๋๋ค. (1ํ Nํ)# DataFrame.explode(column, ignore_index=False)
# Before
# A | B
# 1 | [a, b]
df.explode('B')
# After
# A | B
# 1 | a
# 1 | bmerge (SQL Join ๋ฐฉ์)๋ DataFrame์ ํน์ ํค(Key)๋ฅผ ๊ธฐ์ค์ผ๋ก ๋ณํฉํฉ๋๋ค. SQL์ Join๊ณผ ๋์ผํฉ๋๋ค.
# DataFrame.merge(right, how='inner', on=None, left_on=None, right_on=None,
# left_index=False, right_index=False, sort=False, suffixes=('_x', '_y'),
# copy=None, indicator=False, validate=None)
on: ๊ธฐ์ค์ด ๋๋ ์ปฌ๋ผ๋ช
. (๋ DF์ ์ปฌ๋ผ๋ช
์ด ๋ค๋ฅด๋ฉด left_on, right_on ์ฌ์ฉ)how:'inner': ๊ต์งํฉ (๋ ๋ฐ์ดํฐ์ ๋ชจ๋ ์๋ ํค๋ง ๋จ๊น). (๊ธฐ๋ณธ๊ฐ)'outer': ํฉ์งํฉ (๋ชจ๋ ํค๋ฅผ ๋จ๊ธฐ๊ณ , ๋น ๊ณณ์ NaN).'left': ์ผ์ชฝ ๋ฐ์ดํฐํ๋ ์์ ํค๋ฅผ ๋ชจ๋ ์ ์ง.'right': ์ค๋ฅธ์ชฝ ๋ฐ์ดํฐํ๋ ์์ ํค๋ฅผ ๋ชจ๋ ์ ์ง.concat (Concatenate, ๋ฌผ๋ฆฌ์ ๊ฒฐํฉ)๋ ๊ฐ ์ด์์ DataFrame์ ๋ฌผ๋ฆฌ์ ์ผ๋ก ์ด์ด ๋ถ์ ๋๋ค.
# DataFrame.concat(objs, *, axis=0, join='outer', ignore_index=False, keys=None,
# levels=None, names=None, verify_integrity=False, sort=False, copy=None)
axis=0(๊ธฐ๋ณธ๊ฐ): ์์๋๋ก ๋ถ์ด๊ธฐ (ํ ์ถ๊ฐ).ignore_index=True: ๊ธฐ์กด ์ธ๋ฑ์ค๋ฅผ ๋ฌด์ํ๊ณ ์๋ก ๋ฒํธ๋ฅผ ๋งค๊ธฐ๊ธฐ.axis=1: ์ข์ฐ๋ก ๋ถ์ด๊ธฐ (์ด ์ถ๊ฐ).๋ ๋ณ์ ๊ฐ์ ๊ด๊ณ์ ๊ฐ๋์ ๋ฐฉํฅ์ ์์นํํ๋ ํต๊ณ ๊ธฐ๋ฒ์ ๋๋ค.
method ํ๋ผ๋ฏธํฐ)corr() ๋ฉ์๋# DataFrame.corr(method='pearson', min_periods=1, numeric_only=False)
# ์๊ด ๊ณ์ ํ๋ ฌ ๊ณ์ฐ
corr_matrix = df.corr(numeric_only=True)
# ์๊ฐํ (Seaborn Heatmap)
import seaborn as sns
sns.heatmap(corr_matrix, annot=True, cmap='coolwarm')
์๊ด ๋ถ์ ๊ฒฐ๊ณผ๋ seaborn.heatmap์ ํตํด ์๊ฐํํ๋ฉด ๊ด๊ณ๋ฅผ ํ๋์ ํ์
ํ๊ธฐ ์ข์ต๋๋ค.
import seaborn as sns
import matplotlib.pyplot as plt
corr_matrix = df.corr(numeric_only=True) # ์์นํ ๋ฐ์ดํฐ๋ง ๊ณ์ฐ
sns.heatmap(corr_matrix, annot=True, cmap='coolwarm', vmin=-1, vmax=1)
plt.show()