Pandas ๋ผ์ด๋ธ๋ฌ๋ฆฌ ์ฌ์ฉ๋ฒ
BoostCamp AI Tech
Python
Pandas
01/27/2021
๋ณธ ์ ๋ฆฌ ๋ด์ฉ์ Naver BoostCamp AI Tech์ edwith์์ ์๊ฐํ ๋ด์ฉ์ ์ ๋ฆฌํ ๊ฒ์
๋๋ค.
์ฌ์ค๊ณผ ๋ค๋ฅธ ๋ถ๋ถ์ด ์๊ฑฐ๋, ์์ ์ด ํ์ํ ์ฌํญ์ ๋๊ธ๋ก ๋จ๊ฒจ์ฃผ์ธ์.
Pandas
panel datas
์์ ๋์จ ์ด๋ฆ์ผ๋ก, ๊ตฌ์กฐํ๋ ๋ฐ์ดํฐ์ ์ฒ๋ฆฌ๋ฅผ ์ง์ํ๋ Python์ ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ด๋ค. Python์ ์์
์ด๋ผ๊ณ ํ ์ ์๋ค.
- ๊ณ ์ฑ๋ฅ array ๊ณ์ฐ์ฉ ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ธ numpy์ ํตํฉํ์ฌ ๊ฐ๋ ฅํ ์คํ๋ ๋์ํธ ์ฒ๋ฆฌ ๊ธฐ๋ฅ์ ์ ๊ณตํ๋ค.
- ์ธ๋ฑ์ฑ, ์ฐ์ฐ์ฉ ํจ์, ์ ์ฒ๋ฆฌ ํจ์ ๋ฑ์ ์ ๊ณตํ๋ค.
- ๋ฐ์ดํฐ ์ฒ๋ฆฌ ๋ฐ ํต๊ณ ๋ถ์์ ์ํด ์ฌ์ฉ๋๋ค.
- Tabular ๋ฐ์ดํฐ(ํ ์ด๋ธํ ๋ฐ์ดํฐ)๋ฅผ ๋ค๋ฃจ๋ ๋ฐ์ ์ต์ ํ๋์ด์๋ค.
์ด ์ค, Data Table ์ ์ฒด๋ฅผ ํฌํจํ๋ ๊ฐ์ฒด๋ฅผ DataFrame
, Column ํ๋์ ํด๋นํ๋ ๋ฐ์ดํฐ์
๊ฐ์ฒด๋ฅผ Series
๋ผ๊ณ ํ๋ค.
Series
list_data = [1,2,3,4,5]example_obj = Series(data = list_data)example_obj'''0 11 22 33 44 5dtype: int64'''
data
ํ๋ผ๋ฏธํฐ๋ฅผ ๋ฐ์ ๊ฐ์ฒด๋ฅผ ์์ฑํ๋ฉฐ, Numpy
์ ndarray
๋ฅผ ๊ธฐ๋ฐ์ผ๋ก ๋ง๋ค์ด์ง, Pandas
์์ ์ฌ์ฉํ๊ธฐ ์ํ wrapper ๊ฐ์ฒด๋ผ๊ณ ๋ณผ์๋ ์๋ค.(Subclass of numpy.ndarray
)
ํน์ดํ ์ ์, ์์ ๊ฐ์ด [1,2,3,4,5]
๋ผ๋ ๋ฐ์ดํฐ๋ง ๋ค์ด๊ฐ๋๊ฒ์ด ์๋๋ผ, ์ด ๋ฐ์ดํฐ์ ์ธ๋ฑ์ค ๊ฐ [0,1,2,3,4]
๋ ๊ฐ์ด ์ ์ฅ๋๋ค. ์ด ์ธ๋ฑ์ค๊ฐ์ ๋ฌธ์์ด๋ก๋ ์ง์ ๊ฐ๋ฅํ๋ค.
Series ๊ฐ์ฒด๋ฅผ ์์ฑํ ๋, Index๋ฅผ ๊ธฐ์ค์ผ๋ก ์์ฑํ๋ฏ๋ก ๋ง์ฝ data๊ฐ ์๋ index๊ฐ ์๋ค๋ฉด NaN๊ฐ์ด ์ฑ์์ง๋ค.
- data์ index๋ฅผ ๋ฐ๋ก ๋ช ์ํ๋ ๋์ dict ํ์ ์ ๋ฃ์ด ํ๋ฒ์ ์ง์ ํ ์๋ ์๋ค.
name
์ผ๋กSeries
๊ฐ์ฒด ์์ฒด์ ์ด๋ฆ์ ์ ํด์ค ์ ์๋ค.index.name
์ผ๋ก ์ธ๋ฑ์ค์ ์ด๋ฆ์ ์ง์ ํด์ค ์ ์๋ค.as_type
์ผ๋ก ๋ฐ์ดํฐ ํ์ ์ ๋ณ๊ฒฝํ ์ ์๋ค.
# ์ธ๋ฑ์ค ๋ฌธ์์ด๋ก ๋ฐ๊พธ๊ธฐlist_data = [1,2,3,4,5]list_name = ["a","b","c","d","e"]example_obj = Series(data = list_data, index=list_name)example_obj'''a 1b 2c 3d 4e 5dtype: int64'''# dict ํ์
์ผ๋ก ์์ฑํ๊ธฐdict_data = {"a":1, "b":2, "c":3, "d":4, "e":5}example_obj = Series(dict_data, dtype=np.float32, name="example_data")# series ๊ฐ์ฒด ์ด๋ฆ ์ง์ example_obj.name = "number"# index ์ด๋ฆ ์ง์ example_obj.index.name = "alphabet"# ๋ฐ์ดํฐ ํ์
(dtype) ๋ณ๊ฒฝํ๊ธฐexample_obj = example_obj.astype(int)
Dataframe
Numpy
์ 2์ฐจ์ ndarray
์ ๋น์ทํ ๊ฐ์ฒด์ด๋ฉฐ, Series
์ ๋ฌ๋ฆฌ (row) index ๋ฟ๋ง ์๋๋ผ column index๋ ์๋ค. ๊ฐ ์ปฌ๋ผ์ ๋ค๋ฅธ ๋ฐ์ดํฐ ํ์
์ ๊ฐ์ง ์ ์์ผ๋ฉฐ, ์ปฌ๋ผ์ ๋ผ๊ณ ๋ถ์ผ ์ ์์ผ๋ฏ๋ก ๋ฐ์ดํฐํ๋ ์์ ์ ์ฒด ์ฌ์ด์ฆ๋ mutableํ๋ค.
Series ๊ฐ์ฒด๋ฅผ ์์ฑํ ๋์ฒ๋ผ, Index๋ฅผ ๊ธฐ์ค์ผ๋ก ์์ฑํ๋ฏ๋ก ๋ง์ฝ data๊ฐ ์๋ row ๋๋ column index๊ฐ ์๋ค๋ฉด NaN๊ฐ์ด ์ฑ์์ง๋ค.
- ์ธ๋ฑ์ฑ์ผ๋ก
loc
๊ณผiloc
์ ์ฌ์ฉํ ์ ์๋ค. (Series
๊ฐ์ฒด๋ ํต์ฉ)loc
์ ์ค์ index name๊ณผ ์ผ์นํ๊ฒ ์ฌ์ฉํด์ผํ๋ค. (์ซ์, ๋ฌธ์์ด)iloc
์ index์ position ๊ฐ์ ์ฌ์ฉํ๋ค.(0๋ถํฐ n๊น์ง์ ์ซ์)- ๋ ์ธ๋ฑ์ฑ ๋ชจ๋ row์ column์ ๋ชจ๋ ์ง์ ํด์ค ์ ์๋ค.
- column์ ์๋ก์ด ๋ฐ์ดํฐ๋ฅผ ํ ๋นํ ์ ์๋ค.
- comparison ๋ฑ์ผ๋ก boolean ๊ฐ์ ๋ฃ์ ์๋ ์๋ค. (
Numpy
์fancy index
)
- comparison ๋ฑ์ผ๋ก boolean ๊ฐ์ ๋ฃ์ ์๋ ์๋ค. (
df.T
๋ก row์ column ์ธ๋ฑ์ค๋ฅผ ๋ฐ๊ฟ ์ ์๋ค.values
๋ฅผ ์ฌ์ฉํ์ฌ ๋ฐ์ดํฐndarray
๋ฅผ ๋ฝ์๋ผ ์ ์๋ค.- ์ปฌ๋ผ์ ์ญ์ ํ ๋, ๋๊ฐ์ง ๋ฐฉ๋ฒ์ ์ด์ฉํ ์์๋ค.
- ์ปฌ๋ผ ์ญ์ ์,
del df['์ปฌ๋ผ๋ช ']
- ๋ฉ๋ชจ๋ฆฌ ์ฃผ์๊น์ง ์ญ์ df.drop('์ปฌ๋ผ๋ช ', axis=n)
์๋ณธ ๋ฐ์ดํฐ ํ๋ ์์ ๋ณ๊ฒฝํ์ง ์๊ณ , ํด๋น ์ปฌ๋ผ์ ์ญ์ ํ ๋ฐ์ดํฐํ๋ ์์ ๋ฐํํ๋ค.
- ์ปฌ๋ผ ์ญ์ ์,
raw_data = {'first_name': ['Jason', 'Molly', 'Tina', 'Jake', 'Amy'], 'last_name': ['Miller', 'Jacobson', 'Ali', 'Milner', 'Cooze'], 'age': [42, 52, 36, 24, 73], 'city': ['San Francisco', 'Baltimore', 'Miami', 'Douglas', 'Boston']}df = pd.DataFrame(raw_data, columns = ['first_name', 'last_name', 'age', 'city'])df.first_name # == df["first_name"], series ๋ฐ์ดํฐํ# ์ธ๋ฑ์ฑs = pd.Series(np.nan, index=[49,48, 1, 2])s.loc[:1] # ์ธ๋ฑ์ค ์ด๋ฆ์ด 1์ธ row ๊น์ง๋ง'''49 NaN48 NaN1 NaN'''s.iloc(:1] # ์ธ๋ฑ์ค ์์น๊ฐ 1์ธ row๊น์ง๋ง'''49 NaN'''# column์ ์๋ก์ด ๋ฐ์ดํฐ ํ ๋นdf.debt = df.age > 40 # column 'debt'์ comparison์ T/F ๊ฐ ์
๋ ฅํ์ฌ ๋ถ์
Selection & Drop
Selection ๋ฐฉ์
- ๋ฐ์ดํฐ์ ํ์
์ ์ฒดํนํ ๋
head().T
๋ฅผ ์ฌ์ฉํ์ฌ ์ปฌ๋ผ์ ์ฌ๋ฐ๋ฅธ ๊ฐ์ด ๋ค์ด๊ฐ๋์ง ํ์ธํ๊ธฐ๋ ํ๋ค. - n๊ฐ์ ์ปฌ๋ผ๋ช ์ ๋ฆฌ์คํธ๋ก ์ง์ ํ์ฌ ํด๋น ์ปฌ๋ผ ๋ฐ์ดํฐ๋ค์ ๋ฝ์์ฌ ์ ์๋ค.
- ์ปฌ๋ผ๋ช ์ ์ง์ ํ์ง ์์์ ์, index number๋ก ํด๋น row๋ฅผ ๋ฝ์์ฌ ์ ์๋ค.
Numpy
์fancy index
์ฒ๋ผ, ์กฐ๊ฑด์์ ๋ฃ์ด ์ฌ์ฉํ ์๋ ์๋ค.- Index name ๋ณ๊ฒฝ๋ ๊ฐ๋ฅํ๋ค.
# ์ปฌ๋ผ ๋ฐ์ดํฐ ํ์
ํ์ธdf.head(3).T# ์ปฌ๋ผ๋ช
์ง์ df["a"].head(2)df[["a", "b", "c"]].head(3)# ์ปฌ๋ผ๋ช
์์ด ์ฌ์ฉํ๋ ์ธ๋ฑ์ค ์ง์ ์ row๋ฅผ ํ์ํ๋ค.df[:3] # == df[[0,1,2]], 0,1,2 row ํ์# ์กฐ๊ฑด์ ๋ฃ์ด selectiondf[20 < "age" < 40]
loc
, iloc
์ ํ์ฉํ selection
loc
, iloc
์ ํ์ฉํ selection๋ ํ์ธํด๋ณด์.
- ๊ธฐ๋ณธ ๋ฐฉ์
- ์ปฌ๋ผ๋ช ์ ๋ช ์ํ๊ณ , index number๋ฅผ ๋ฃ์ด row์ ๊ฐ์๋ฅผ ์ง์ ํ๋ค.
loc
- index name์ ๋ฃ์ด row๋ฅผ ์ง์ ํ ๋ค, ์ปฌ๋ผ๋ช ์ ๋ช ์ํ๋ค.
iloc
- ์ปฌ๋ผ number๋ฅผ ์ง์ ํ ๋ค, index number๋ฅผ ์ง์ ํด row๋ ๋ช ์ํ๋ค.
# basic# ์ปฌ๋ผ๋ช
๊ณผ row index ์ซ์df[["name","street"]][:2]# loc# row index ๋ช
๊ณผ ์ปฌ๋ผ๋ช
df.loc[['c','e'],["name","street"]]# iloc# ์ปฌ๋ผ ์ซ์์ row index ์ซ์df.iloc[:2,:2]
Index ์ฌ๊ตฌ์ฑ
๋ ๊ฐ์ง ๋ฐฉ์์ด ์๋ค.
- ์ง์ ์ง์
reset_index
ํจ์ ์ฌ์ฉ
# ์ง์ ์ง์ ํด์ฃผ๊ธฐdf.index = list(range(0,10))# ๋ํดํธ ์ธ๋ฑ์ค๋ฅผ ์ถ๊ฐํ ๋ฐ์ดํฐ ํ๋ ์์ ๋ฐํ# ๊ธฐ์กด ์ธ๋ฑ์ค๋ฅผ ๋์ฒดํ๊ณ ์ถ๋ค๋ฉด drop=True ์ต์
df.reset_index(drop=True)# ๋จ, inplace=True ์ต์
์ ์ฌ์ฉํ๋ฉด ์๋ณธ ๋ฐ์ดํฐ ํ๋ ์ ๋ณํ์ '์ ์ฉ'์ํจ๋ค.
์ผ๋ฐ์ ์ผ๋ก ๋ฐ์ดํฐํ๋ ์์ ์๋ณธ์ ์ ์งํ๋๊ฒ์ด ์ปจ๋ฒค์ ์ด์ง๋ง, ๋ถ๋์ดํ๊ฒ ๋ณ๊ฒฝํด์ผํ ๊ฒฝ์ฐ inplace=True ์ต์ ์ ์ฌ์ฉํ์ฌ ๋ณํ์ํ๋ฅผ '์ ์ฉ'์ํจ๋ค.
Drop
df.drop(n)
์ ์ธ๋ฑ์ค๋ฅผ ์ง์ ํ์ฌ ํด๋น row๋ฅผ ์ญ์ ํ ๋ฐ์ดํฐํ๋ ์์ ๋ฐํํ๋ค.axis=1
์ต์ ์ ์ง์ ํ์ฌ column์ ์ญ์ ํ ์ ์๋ค.- ๋ง์ฐฌ๊ฐ์ง๋ก,
inplace=True
์ต์ ์ ์ฌ์ฉํ์ฌ ์๋ณธ ๋ฐ์ดํฐํ๋ ์์ ์์ ํ ์ ์๋ค.
# 1๋ฒ row ์ญ์ df.drop(1)# 'city' column ์ญ์ df.drop("city",axis=1)
๋งคํธ๋ฆญ์ค ๋ณํ
์ด์ธ์๋, as_matrix()
ํจ์๋ก Numpy
ndarray
ํํ๋ก ๋ณํํ ์ ์๋ค.
matrix = df.as_matrix()
Operations
Series Operation
๋ชจ๋ ์ฐ์ฐ์ (row) index๋ฅผ ๊ธฐ์ค์ผ๋ก ์ฐ์ฐ์ ์ํํ๋ค.
๋ฐ๋ผ์ ๊ฒน์น๋ index๊ฐ ์์ ๊ฒฝ์ฐ NaN
๊ฐ์ ๋ฐํํ๋ค.
s1 = Series(range(1,6), index=list("abcde"))s2 = Series(range(5,11), index=list("bcdefg"))# ๊ฒน์น๋ index๋ b,c,d,es1 + s2 # == s1.add(s2)'''a NaNb 7.0c 9.0d 11.0e 13.0f NaNg NaNdtype: float64'''
Dataframe Operation
Series
๋ index๋ง ์ฒดํฌํ์ง๋ง, Dataframe
์ column๊ฐ๊ณผ index๋ฅผ ๊ฐ์ด ๋ณธ๋ค.
๊ฒน์น๋ ์
์ด ์์ ๊ฒฝ์ฐ NaN
์ ๋ฐํํ์ง๋ง, fill_value=
์ต์
์ ์ฌ์ฉํด ๋ค๋ฅธ ๊ฐ์ ๋ํดํธ๋ก ์ง์ ํ ์ ์๋ค.
df1 = DataFrame( np.arange(9).reshape(3,3), columns=list("abc"))df2 = DataFrame( np.arange(16).reshape(4,4), columns=list("abcd"))# df2.loc[3]๊ณผ df2["d"]๊ฐ ๊ฒน์น์ง ์์# df1 + df2df1.add(df2,fill_value=0) # ๊ฒน์น์ง ์์ NaN ๊ฐ์ด ๋ค์ด๊ฐ ์์น๋ฅผ 0์ผ๋ก ์ฑ์
Series + Dataframe
Series
์ Dataframe
์ ๋ค๋ฅธ ํ์
์ด๋ฏ๋ก ๊ฐ์ colum์ ๊ฐ์ง ๊ฒ์ด ์๋๋ผ๋ฉด ๋ชจ๋ ๋ฐ์ดํฐ๊ฐ NaN์ผ๋ก ์ฑ์์ ธ ์ ๋๋ก ์ฐ์ฐ์ด ๋์ง ์๋๋ค.
axis=
์ต์
์ ๋ช
์ํด์ฃผ์ด์ผ ํด๋น ์ถ์ ๊ธฐ์ค์ผ๋ก broadcasting์ ์ํํ๋ค.
df = DataFrame( np.arange(16).reshape(4,4), columns=list("abcd"))s = Series( np.arange(10,14), index=list("abcd"))s2 = Series(np.arange(10,14))# Series๊ฐ Dataframe์ column๊ณผ ๊ฐ์ index์ ๊ฐ์ ธ ๋ฐ๋ก row๋ก ๋ณํ๋๋ ๊ฒฝ์ฐdf + s# Series๊ฐ Dataframe์ column๊ณผ ๋ค๋ฅธ index์ ๊ฐ์ ธ row๋ก ๋ณํ๋์ง ์๋ ๊ฒฝ์ฐdf + s2 # ๋ชจ๋ ๊ฐ์ด NaN์ผ๋ก ์ฑ์์ง# axis๋ฅผ ๊ธฐ์ค์ผ๋ก row broadcasting ์ํdf.add(s2, axis=0)
lambda, map, apply
map
pandas
์ Series
type ๋ฐ์ดํฐ์๋ map
ํจ์๋ฅผ ์ฌ์ฉํ ์ ์๋ค.
์ด ๋, lambda
์ ์กฐํฉํ ์ ์๊ณ , function ๋์ dict, sequence ํ ์๋ฃ ๋ฑ์ผ๋ก ๋์ฒด๋ ๊ฐ๋ฅํ๋ค.
๋น์ทํ ๊ธฐ๋ฅ์ผ๋ก replace
๊ฐ ์๋ค.
map
ํจ์์ ๊ธฐ๋ฅ ์ค ๋ฐ์ดํฐ ๋ณํ๊ธฐ๋ฅ๋ง ๋ด๋นํ๋ค. ์ฆ, map
์ฒ๋ผ ๋ฐ์ดํฐ์ ํจ์๋ฅผ ์ ์ฉํ ์ ์๊ณ , dict์์ ์ ํด์ง value๊ฐ์ผ๋ก ๋ฐ๊ฟ์ฃผ๊ธฐ๋ง ํ๋ค.
# number_df์ ๊ฐ๋ค์ ์ ๊ณฑํ๋ mappingnumber_df.map(lambda x: x**2).head(5)# str ์ฑ๋ณ๊ฐ์ 0,1 ์ฝ๋๊ฐ์ผ๋ก ๋ฐ๊พธ์ด sex_code ์ปฌ๋ผ์ ์ถ๊ฐํ๋ mappingdf["sex_code"] = df.sex.map({"male":0, "female":1})# str ์ฑ๋ณ๊ฐ์ 0,1 ์ฝ๋๊ฐ์ผ๋ก ๋ณํํ์ฌ ์ถ๋ ฅ - replacedf.sex.replace({"male":0, "female":1}).head()# to_replace=๋ณํํ ํค๊ฐ(from), value=๋ณํํ์ฌ ์ ์ฅํ ๊ฐ(to)# to_replace์ ํด๋นํ๋ ๊ฐ์ value์ ์๋ ๊ฐ์ผ๋ก ๋ณํ์ํค๊ฒ ๋คdf["race"].replace(to_replace=key, value=value, inplace=True)
apply
map
ํจ์์ ๋ฌ๋ฆฌ, Series
์ ์ฒด ๋จ์์ ํด๋น ํจ์๋ฅผ ์ ์ฉํ๋ค.
- ์
๋ ฅ๊ฐ์
Dataframe
,Series
๋ชจ๋ ๋ฐ์ ์ ์๋ค. - ์ค์นผ๋ผ ๊ฐ ์ด์ธ์
Series
๊ฐ์ ๋ฐํ๋ ๊ฐ๋ฅํ๋ค.
df_info = df[["earn", "height","age"]]f = lambda x : x.max() - x.min()df_info.apply(f)'''earn 318047.708444height 19.870000age 73.000000dtype: float64'''# Series ๊ฐ ๋ฐํdef f(x): return Series([x.min(), x.max(), x.mean()], index=["min", "max", "mean"])df_info.apply(f)'''earn height agemin -98.580489 57.34000 22.000000max 317949.127955 77.21000 95.000000mean 32446.292622 66.59264 45.32849'''
applymap
apply
์๋ ๋ค๋ฅด๊ฒ, Series
๋จ์๊ฐ ์๋ element ๋จ์๋ก ํจ์๋ฅผ ์ ์ฉํ๋ค.
-
apply
๋ฅผdataframe
์ด ์๋Series
์ ์ ์ฉ์ํค๋ฉด,applymap
๊ณผ ๋์ผํ ๊ธฐ๋ฅ์ ์ํํ๋ค.
f = lambda x : -xdf_info.applymap(f).head(5)# ์์ ์ฝ๋๋ ์๋ ์ฝ๋์ ๋์ผํ ๊ธฐ๋ฅ์ ์ํํ๋ค.# f = lambda x : -x# df_info["earn"].apply(f).head(5)
Pandas Built-in Function
describe
Numeric Type ๋ฐ์ดํฐ๋ค์ ์์ฝ์ ๋ณด๋ฅผ ๋ณด์ฌ์ค๋ค.
df.describe()
unique
Series
๋ฐ์ดํฐ์ ์๋ ์ ์ผํ ๊ฐ(์ค๋ณต์ ์ ์ธํ ๊ฐ)๋ค์ list๋ก ๋ฐํํ๋ค.
df.race.unique()'''array(['white', 'asian', 'hispanic', 'black', 'other'], dtype=object)'''
sum
๊ธฐ๋ณธ์ ์ธ column ๋๋ row ๊ฐ์ ํฉ์ฐ์ฐ์ ์ง์ํ๋ค.
์ด์ธ์๋ ๋น์ทํ ๊ธฐ๋ฅ์ ํจ์๋ค์ด ๋ง๋ค.
sub
,mean
,min
,max
,count
,median
,mad
,var
๋ฑ
# ์ปฌ๋ผ๋ณ ํฉdf.sum(axis=0)# row๋ณ ํฉdf.sum(axis=1)
isnull
column ๋๋ row ๊ฐ ์ค NaN
(null) ๊ฐ์ index๋ฅผ ๋ฐํํ๋ค.
sum
ํจ์๋ฅผ ์ฒด์ด๋ํ์ฌ Null์ธ ์ ์ด ๋ช๊ฐ ์๋์ง ํ์ธํ ์๋ ์๋ค.
# null์ธ data์ index๋ฅผ ๋ฐํdf.isnull()# Null์ธ ์
๊ฐ์ ํ์ธdf.isnull().sum()
sort_values
column ๊ฐ์ ๊ธฐ์ค์ผ๋ก ๋ฐ์ดํฐ๋ฅผ ์ ๋ ฌํ๋ค.
- ์ต์ ์ ๋ช ์ํด ์ค๋ฆ์ฐจ์, ๋ด๋ฆผ์ฐจ์๋ฑ์ ์ง์ ํ ์ ์๋ค.
# ascending=False ์ ๋ด๋ฆผ์ฐจ์df.sort_values(["age","earn"], ascending=True).head()
Correlation & Covariance
์๊ด๊ณ์์ ๊ณต๋ถ์ฐ์ ๊ตฌํด์ค๋ค.
corr
,cov
,corrwith
# df.[์ปฌ๋ผ1].ํจ์(df.[์ปฌ๋ผ2])df.age.corr(df.earn)df.age.cov(df.earn)df.corrwith(df.earn)# ๋ชจ๋ ์ปฌ๋ผ๋ค๊ฐ์ ์๊ด๊ด๊ณ๋ฅผ ๋ค ๋ณด์ฌ์ค๋คdf.corr()
ํต๊ณํจ์
Groupby
ํต๊ณ ๋ฐ์ดํฐ๋ฅผ ๋ด๊ธฐ ์ํ ํจ์๋ก, ํน์ ์ปฌ๋ผ์ ๊ฐ์ ์ง์ ํด ํด๋น ๊ฐ์ ๊ฐ์ง row๋ค์ SeriesGroupBy
๊ฐ์ฒด๋ก ๋ฌถ๊ณ , ์ฒด์ด๋ ํต๊ณ ์ฐ์ฐ์ผ๋ก ํต๊ณํํ์ฌ ๋ณด์ฌ์ค๋ค.
# phone_data.csv ํ์ผ ๋ค์ด๋ก๋!wget https://www.shanelynn.ie/wp-content/uploads/2015/06/phone_data.csv
df_phone = pd.read_csv('./data/phone_data.csv')df_phone.dtypes'''...date object...'''# ๋ฌธ์์ด ํ์
์ date ์ปฌ๋ผ ๊ฐ์ ๊ฐ๊ฐ(apply) ํ์ฑํ์ฌ datetime ํ์
์ผ๋ก ๋ณํ# parse ํจ์์ argument์์ '์ผ(day)'๊ฐ '์(month)'๋ณด๋ค ๋จผ์ ๋์จ๋ค๋ฉด dayfirst=Truedf_phone['date'] = df_phone['date'].apply(dateutil.parser.parse, dayfirst=True)df_phone.dtypes'''date datetime64[ns]'''# datetime ํ์
์ ์๋ณ๋ก ๋ฌถ์ด, duration(ํตํ์๊ฐ)์ ํฉ๊ณ๋ฅผ matplotlib๋ก ๊ทธ๋ํ ํ์df_phone.groupby("month")["duration"].sum().plot()# month์ item๋ณ๋ก ๋ฌถ์ด duration count# unstack์ผ๋ก row ์ธ๋ฑ์ค ๊ฐ๋ค์ column ์ธ๋ฑ์ค๋ก ์ฌ๊ตฌ์ฑํด ๋ณผ ์ ์๋ค.df_phone.groupby(['month','item'])['duration'].count().unstack().plot()# month๋ก ๋ฌถ๋, ์ธ๋ฑ์ค๋ก ์ผ์ง๋ ๋ง๊ฒ(as_index=False)# duration์๋ sum์ ์ ์ฉ์ํฌ๊ฒ(agg({"duration":"sum"}))# aggํจ์๋ ๊ทธ๋ฃน์ ๋ํ์ฌ ์ฌ์ฉ์๊ฐ ์ ์ํ ์ง๊ณํจ์๋ฅผ ์ ์ฉํ ์ ์๋ค.df_phone.groupby("month", as_index=False).agg({"duration":"sum"})# df_phone.groupby("month").agg({"duration":"sum"}).reset_index # ๋น์ทํ ๊ฒฐ๊ณผ# group ํ์
๊ฐ์ฒด๋ฅผ ๋ง๋ค์๋ค๋ฉดgroup.add_prefix('duration_') # ์ปฌ๋ผ์ด๋ฆ์ ์ ๋์ฌ ์ถ๊ฐํ๊ธฐ
์์ธํ ์ค๋ช ์ ๋ค์ ๋ธ๋ก๊ทธ๋ฅผ ์ฐธ๊ณ ํ๋ค.
[Python Data Analysis]24.๋ฐ์ดํฐ ๊ทธ๋ฃนํ ํจ์ ์ดํดํ๊ธฐ
Pivot Table
์ปฌ๋ผ์ labeling๊ฐ์ ์ถ๊ฐํ์ฌ Value์ numeric type ๊ฐ์ aggregation
ํ๋ ํํ
groupby
+ unstack
์ ์กฐํฉ์ผ๋ก๋ ์ํํ ์ ์์ง๋ง, ์ก์
์ ์ฌ์ฉํ๋๊ฒ์ด ์ต์ํ๋ค๋ฉด pivot_table
์ ์ฌ์ฉํ๋๊ฒ์ด ์ข ๋ ์ฝ๋ค.
# ๊ฐ ๋ฐ์ดํฐ์ value ์์น์ ๋ค์ด๊ฐ ๊ฐ์ ["rating"] ์ปฌ๋ผ๊ฐ๋ค ์ค ํ๋๋ก ์ ํ๋ค.# critic์ ๊ฐ๋ค์ row index๋ก ํ๊ณ , title์ ๊ฐ๋ค์ columns๋ก ๊ตฌ์ฑํ๋ค.# ๊ฐ value์ aggfunction "sum"์ ์ ์ฉํ๊ณ , NaN๊ฐ์ 0์ผ๋ก ์ฑ์ด๋ค.df_movie.pivot_table(["rating"], index=df_movie.critic, columns=df_movie.title, aggfunc="sum", fill_value=0)
Crosstab
๋ ์ปฌ๋ผ์ ๊ต์ฐจ ๋น๋, ๋น์จ, ๋ง์
๋ฑ์ ๊ตฌํ ๋ ์ฌ์ฉํ๋ ํจ์๋ก, pivot_table
์ ํน์ ํํ์ด๋ค.
- User-Item Rating ํ๋ ฌ๋ฑ์ ๋ง๋ค ๋ ์ฌ์ฉํ๋ค.
# ์ธ ํจ์๋ ๊ฐ์ ์ญํ ์ ํ๋ค.df_movie.groupby(["critic","title"]).agg({"rating":"first"}).unstack().fillna(0)df_movie.pivot_table(["rating"], index=df_movie.critic, columns=df_movie.title, aggfunc="sum", fill_value=0)pd.crosstab(index=df_movie.critic,columns=df_movie.title,values=df_movie.rating, aggfunc="first").fillna(0)
Merge & Concat
Merge
SQL
์์ ๋ง์ด ์ฌ์ฉํ๋ Merge์ ๊ฐ์ ๊ธฐ๋ฅ์ผ๋ก, ๊ฒน์น๋ ์ปฌ๋ผ ๋ฐ์ดํฐ๋ฅผ ๊ธฐ์ค์ผ๋ก ๋๊ฐ์ ๋ฐ์ดํฐํ๋ ์์ ํ๋๋ก ํฉ์น๋ ๊ธฐ๋ฅ์ด๋ค.
- ๋ ๋ฐ์ดํฐํ๋ ์์ ๊ฐ์ ์ด๋ฆ์ ์ปฌ๋ผ์ด ์๋ค๋ฉด,
on='column_name'
์ต์ ์ผ๋ก ๊ธฐ์ค์ ์ ๋ง๋ ๋ค. - ๋ ์ปฌ๋ผ์ด ๋ฐ์ดํฐ๋ ๊ฐ์ง๋ง ์ด๋ฆ์ ๋ค๋ฅด๋ค๋ฉด,
left_on='left_column_name'
,right_on='right_column_name'
์ผ๋ก ๊ธฐ์ค์ ์ ๋ง๋ ๋ค.
JOIN
์ ์ข
๋ฅ
how=
์ต์ ์ ์ด์ฉํด join์ ์ข ๋ฅ๋ฅผ ์ง์ ํด์ค ์ ์๋ค.how=inner
: ๋ํดํธ๋ก, ๋ ์ปฌ๋ผ์์ ๊ฒน์น๋ ๊ฐ์ ๊ธฐ์ค์ผ๋ก ์ธ๋ฑ์ค๋ฅผ ๊ตฌ์ฑํ๋ค.how=left(right)
: left(right) ์ปฌ๋ผ์ ๊ฐ์ ๊ธฐ์ค์ผ๋ก ์ธ๋ฑ์ค๋ฅผ ๊ตฌ์ฑhow=outer
: ๋ ์ปฌ๋ผ์ ๋ชจ๋ ๊ฐ์ ์ธ๋ฑ์ค๋ก ์ฌ์ฉํ๋ฉฐ, ์๋ ๊ฐ์NaN
์ ๋ฃ๋๋ค.
index ์ปฌ๋ผ์ ๊ธฐ์ค์ผ๋ก ํ ์ด๋ธ์ ๊ทธ๋๋ก ๋ถ์ผ์๋ ์๋ค.
right_index=True, left_index=True
# ๊ฐ์ ์ด๋ฆ์ ์ปฌ๋ผ์ ๊ธฐ์ค์ผ๋ก joinpd.merge(df_a, df_b, on='subject_id')# ๋ค๋ฅธ ์ด๋ฆ์ ์ปฌ๋ผ์ ํ๋์ ์ปฌ๋ผ์ผ๋ก ๋ณด๊ณ , ์ด๋ฅผ ๊ธฐ์ค์ผ๋ก joinpd.merge(df_a, df_b, left_on='subject_id_a', right_on='subject_id_b')# left joinpd.merge(df_a, df_b, on='subject_id', how='left')# outer joinpd.merge(df_a, df_b, on='subject_id', how='outer')# ์ธ๋ฑ์ค๋ฅผ ๊ธฐ์ค์ผ๋ก joinpd.merge(df_a, df_b, right_index=True, left_index=True)
concat
๊ฐ์ ํํ์ ๋ฐ์ดํฐ๋ฅผ ๋ถ์ด๋ ์ฐ์ฐํจ์๋ค.
append
๋ฅผ ์ฌ์ฉํด์ ๋น์ทํ ๊ฒฐ๊ณผ๋ฅผ ๋ผ ์ ์๋ค.- ๋ํดํธ๋ ์ธ๋ก๋ก ๋ถ์ด์ง๋ง(ํ ์ถ๊ฐ), ๊ฐ๋ก๋ก ๋ถ์ผ์๋ ์๋ค(์ด ์ถ๊ฐ).
- ๋ฌผ๋ก , ์ธ๋ก๋ก ๋ถ์ผ ๊ฒฝ์ฐ ๊ฐ์ ์ปฌ๋ผ์ ๊ฐ์ง๊ณ ์์ด์ผ ๋ถ์ผ ์ ์๋ค.
axis=1
์ต์ ์ผ๋ก ๊ฐ๋ก๋ก ๋ถ์ผ ์ ์๋ค.
# ์ธ๋ก๋ก ๋ถ์ด๊ธฐdf_new = pd.concat([df_a, df_b])df_new.reset_index() # ํด์ฃผ์ง ์์ผ๋ฉด, ์ธ๋ฑ์ค๊ฐ ๊ทธ๋๋ก ๋ถ์ด 0,1,2,3,0,1,2, ... ํํ๊ฐ ๋๋ค.#df_a.append(df_b) # ๊ฑฐ์ ๊ฐ์ ๊ธฐ๋ฅ์ ๊ฐ์ง๋ค.# ๊ฐ๋ก๋ก ๋ถ์ด๊ธฐdf_new = pd.concat([df_a, df_b], axis=1)df_new.reset_index()
Persistence
Pandas
์์ I/O๋ฅผ ์ฌ์ฉํด ์์์ฑ ์๋ ๋ฐ์ดํฐ๋ฅผ ์ฌ์ฉํ ์ ์๋ค.
Database Connection
๋ฐ์ดํฐ ๋ก๋ฉ์, db connection ๊ธฐ๋ฅ์ ์ ๊ณตํ๋ค.
import sqlite3 # pymysql์ ๋ฏธ๋ฆฌ ์ค์นํ ๊ฒ!conn = sqlite3.connect(".sqlite_example.db")cur = conn.cursor()cur.execute("select * from name limit 5;") # SQL๋ฌธ ์ง์ ์ฌ์ฉ ๊ฐ๋ฅresults = cur.fetchall()results
XLS Persistence
๋ฐ์ดํฐํ๋ ์ ๋จ์๋ก ์์ ๊ฐ์ ์ถ์ถํ๊ฑฐ๋ ์ธ ์ ์๋ค.
openpyxl
๋๋ XlsxWriter
๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ์ค์นํด์ผํ๋ค.
writer = pd.ExcelWriter('./data/df_routes.xlsx', engine='xlsxwriter')# ์ก์
ํํ๋ก ์ ์ฅdf_routes.to_excel(writer, sheet_name='Sheet1')
Pickle Persistence
์์ ๊ณผ ๋์ผํ๊ฒ ํผํดํํ๋ก๋ ์ฝ๊ณ ์ธ ์ ์๋ค.
df_routes_pickle = pd.read_pickle("./data/df_routes.pickle")df_routes_pickle.head()
- ๊ฒฝ์ฌํ๊ฐ๋ฒ(Gradient Descent)์ ๊ธฐ์ด์ ์ดํด
- ๋ฅ๋ฌ๋์ ๊ธฐ์ด์ ์ดํด - ์ ํ๋ชจ๋ธ๋ถํฐ ์ญ์ ํ์ ์ด๋ฅด๊ธฐ๊น์ง