Datalogy

[데이터 전처리] Python 라이브러리 Pandas

thebuck104 2024. 7. 18. 15:24

 

Python Library - Pandas

파이썬은 다음과 같은 유용한 라이브러리들이 많다

 

 

Pandas는 데이터를 전처리 할 때 사용할 수 있는 Python의 라이브러리 중 하나로,

크게 다음과 같은 데이터 오브젝트 형태를 가진다.

 

 

 

Pandas 기본 코드들

불러오고 저장하기

import pandas as pd
import seaborn as sns

data = sns.load_dataset('tips')
data.to_csv("tips_data.csv", index = False)

df = pd.read_csv("tips_data.csv")
#df = pd.read_csv("tips_data.csv", index_col = 0)

df.to_excel("tips_data.xlsx", index = False)

 

 

Index

df = pd.DataFrame({
    "A": [1,2,3] ,
    "B": ["a", "b" , "c"]
}, index = ["idx1","idx2","idx3"])

# loc - 인덱스 이름으로 찾기
df.loc["idx2"]

# A    2
# B    b
# Name: idx2, dtype: object

# 인덱스 sorting
df.sort_index()

#	A	B
# idx1	1	a
# idx2	2	b
# idx3	3	c

# 컬럼을 인덱스로 만들기
df.set_index("A")

#	B
#  A	
#  1 	a
#  2 	b
#  3	c

#인덱스 이름 바꾸기
df.index = [1,2,3]

#	A	B
# 1	1	a
# 2	2	b
# 3	3	c

#인덱스 리셋하기
df.reset_index()

#	index	A	B
# 0	1	1	a
# 1	2	2	b
# 2	3	3	c

#인덱스 인덱스컬럼 없이 리셋하기
df.reset_index(drop=True)

#	A	B
# 0	1	a
# 1	2	b
# 2	3	c

 

 

Columns

data = {
    "name" : ["Alice", "Bob", "Charlie"],
    "age" : [25,30,35],
    "gender" : ["female", "male", "male"]}

df = pd.DataFrame(data)

#	name	age	gender
# 0	Alice	25	female
# 1	Bob	30	male
# 2	Charlie	35	male

#컬럼 이름으로 호출하기
df["name"]

# 0      Alice
# 1        Bob
# 2    Charlie
# 3      David
# 4        Eva
# Name: name, dtype: object

#컬럼 확인하기
df.columns

# Index(['name', 'age', 'gender'], dtype='object')

#컬럼 이름 바꾸기1
df.columns = ["이름", "나이", "성별"]

#	이름	나이	성별
# 0	Alice	25	female
# 1	Bob	30	male
# 2	Charlie	35	male

#컬럼 이름 바꾸기2
df = df.rename(columns = {"이름": "name"})
df = df.rename(columns = {"나이": "age", "성별":"gender"})

#	name	age	gender
# 0	Alice	25	female
# 1	Bob	30	male
# 2	Charlie	35	male

#컬럼과 값들 추가하기
df["스포츠"] = ["축구", "야구", "농구"]

#	name	age	gender	스포츠
# 0	Alice	25	female	축구
# 1	Bob	30	male	야구
# 2	Charlie	35	male	농구

#컬럼 삭제하기
del df["스포츠"]

#	name	age	gender
# 0	Alice	25	female
# 1	Bob	30	male
# 2	Charlie	35	male

 

 

데이터 확인하기

import pandas as pd

df = pd.read_csv("tips_data.csv")

#앞 3개만 호출하기
df.head(3)

#데이터프레임 정보보기
df.info()

#데이터프레임 통계 요약하기
df.describe() 

#	total_bill	tip	size
# count	244.000000	244.000000	244.000000
# mean	19.785943	2.998279	2.569672
# std	8.902412	1.383638	0.951100
# min	3.070000	1.000000	1.000000
# 25%	13.347500	2.000000	2.000000
# 50%	17.795000	2.900000	2.000000
# 75%	24.127500	3.562500	3.000000
# max	50.810000	10.000000	6.000000

#NA 값 찾기
df.isna()

#NA 값이 있는 것들만 호출
df[df["B"].isna()]

 

 

데이터 타입

df = pd.read_csv("tips_data.csv")
df.info() # 데이터프레임 데이터 타입 확인

#컬럼별 데이터 타입 확인하기
df.dtypes

#컬럼 이름으로 컬럼 데이터타입 확인하기
df["total_bill"].dtype

#데이터 타입 바꾸고 저장하기
df["total_bill"] = df["total_bill"].astype(str)

# string을 float으로 바꾸고 다시 int로 바꾸기
df["total_bill"] = df['total_bill'].astype(float).astype(int)

 

 

데이터 선택

iloc

df = pd.DataFrame({
    "A": [1,2,3,4,5],
"B": [10,20,30,40,50],
"C": [100,200,300,400,500]
})

#인덱싱 해서 loc 하기 - iloc
df.iloc[0:5:2] # row 0 부터 row 5 까지, 2씩 건너뛰어서 호출

#	A	B	C
# 0	1	10	100
# 2	3	30	300
# 4	5	50	500

#iloc2
df.iloc[0,1] # row 0, col 1
df.iloc[0, 0:3] # row 0, col 1-2

 

 

loc

df = pd.DataFrame({
    "A": [1,2,3,4,5],
"B": [10,20,30,40,50],
"C": [100,200,300,400,500]
}, index = ["a", "b", "c", "d", "e"])

#모든 데이터 출력
df.iloc[:]

#부분 출력
df.loc["a":"b", "A":"B"]  # row a-b의 col A-B 모두 출력

#slicing and selection
df.loc[:, "A"]  # 모든 row의 col A 출력

df[["A","C"]]  # col A와 C 출력

#부분 출력 2
df.loc["a":"b", ["C", "A"]] # row a-b의 col C 와 col B 모두 출력

 

 

Bolean indexing

조건 호출

df = pd.read_csv("tips_data.csv")

# 조건 호출
df[df["sex"] == "Male"]

# 조건 호출 - and
df[(df["sex"] == "Male") & (df["smoker"] == "Yes")].head(3)

# 조건 호출 - or
df[(df["sex"] == "Male") | (df["smoker"] == "Yes")].head(3)

# 조건 호출 + loc
df.loc[df["size"] > 3, "tip":"smoker"].head(3)

df.loc[df["size"] > 3, ["tip", "day"]].head(3)

# is in
df[df["size"].isin([1,2])]
df[df["day"].isin(["Sun","Mon"])]

# 변수 활용
condition = df['day'] == "Sun"
df[condition]

# 여러 변수
cond1 = df["size"] >= 3
cond2 = df["tip"] < 2

df[cond1 & cond2]
df[cond1 | cond2].head(10)

cond = (df["sex"] == "Male") \
        & (df["tip"] >= 3) \
        & (df["day"] == "Sun")
df[cond].head(10)

 

 

데이터 추가하기, 타입 바꾸기

df["created_at"] = "2024-01-01"
df.info()

df["created_at"] = pd.to_datetime(df["created_at"])
#날짜 타입으로 바꿔주기
df.info()

 

 

데이터 연산하기

# 두 컬럼 더해서 새 컬럼 만들기
df["revenue"] = df["total_bill"] + df["tip"]

# 연산만 해보기
df["total_bill"] + df["tip"]

 

 

데이터 병합

concat

df1 = pd.DataFrame({'A': ['A0', 'A1', 'A2'], 'B': ['B0', 'B1', 'B2']})
df2 = pd.DataFrame({'A': ['A3', 'A4', 'A5'], 'B': ['B3', 'B4', 'B5']})

# 두 데이터프레임 밑으로 붙이기 concat
df = pd.concat([df1, df2]).reset_index(drop=True)
	
#    A	B
# 0	A0	B0
# 1	A1	B1
# 2	A2	B2
# 3	A3	B3
# 4	A4	B4
# 5	A5	B5

# 이건 양옆으로 붙여주기
pd.concat([df1, df2], axis = 1)
# 아래로 붙이는건 axis = 0 임

#	A	B	A	B
# 0	A0	B0	A3	B3
# 1	A1	B1	A4	B4
# 2	A2	B2	A5	B5

# NA값이 있을 수 있음
df3 = pd.DataFrame({'A': ['A3', 'A4', 'A5', "A6"], 'B': ['B3', 'B4', 'B5', "B6"]})
df = pd.concat([df1, df2, df3], axis= 1)

#	A	B	A	B	A	B
# 0	A0	B0	A3	B3	A3	B3
# 1	A1	B1	A4	B4	A4	B4
# 2	A2	B2	A5	B5	A5	B5
# 3	NaN	NaN	NaN	NaN	A6	B6

 

 

merge # sql의 join과 같음

df1 = pd.DataFrame({
    "key": ["a", "b", "c", "d"],
    "value": [1,2,3,4]})

df2 = pd.DataFrame({
    "key": ["d", "d", "f", "g"],
    "value": [5,6,7,8]})
    
# key 를 기준으로 join
pd.merge(df1, df2, on = "key")

#	key	value_x	value_y
# 0	d	4	5
# 1	d	4	6

# inner join
pd.merge(df1, df2, on="key", how = "inner")

#	key	value_x	value_y
# 0	d	4	5
# 1	d	4	6

# outer join
pd.merge(df1, df2, on="key", how = "outer")

#	key	value_x	value_y
# 0	a	1.0	NaN
# 1	b	2.0	NaN
# 2	c	3.0	NaN
# 3	d	4.0	5.0
# 4	d	4.0	6.0
# 5	f	NaN	7.0
# 6	g	NaN	8.0

# left join
pd.merge(df1, df2, on="key", how = "left")

#	key	value_x	value_y
# 0	a	1	NaN
# 1	b	2	NaN
# 2	c	3	NaN
# 3	d	4	5.0
# 4	d	4	6.0

 

 

데이터 집계

Group by

df = pd.DataFrame({
    "category": ['a','b','a','b','a','b'] , 
    "value": [1,2,3,4,5,6]})
    
# group by 와 여러 함수들을 같이 씀
df.groupby("category").mean()

df.groupby("category").sum()

df.groupby("category").count()

df.groupby("category").max()

df.groupby("category").first() # 첫 째 값

# group by 값을 리스트로 반환
df.groupby("category").agg(list) 

# 그 값을 인덱싱 하기
ag = df.groupby("category").agg(list)
ag.iloc[0 , 0]
print (ag.iloc[0 , 0][2])
# 5

# 그 값 iloc 하기
ag.iloc[0:2 , 0]

# category
# a    [1, 3, 5]
# b    [2, 4, 6]
# Name: value, dtype: object

# 그 값 loc 하기
ag.loc[:,"value"]

# category
# a    [1, 3, 5]
# b    [2, 4, 6]
# Name: value, dtype: object

 

심화 집계

df = pd.read_csv("tips_data.csv")

# 하나의 컬럼으로 집계 후 선택 컬럼들의 평균 구하기
k = df[['day', 'total_bill', 'tip', 'size']].groupby("day").mean()

# 여러개의 컬럼으로 집계 하기
df[['sex', 'day', 'total_bill', 'tip', 'size']].groupby(["sex", "day"]).mean()

# 여러개의 컬럼으로 집계 하고, 선택 컬럼 각자 다른 것 구하기
df[['sex', 'day', 'total_bill', 'tip', 'size']].groupby(["day", "sex"])\
.agg({"total_bill":"max", "tip": "mean", "size": "sum"})

 

 

피벗 테이블

기본

df = pd.DataFrame({
    "date": ["2023-01-01", "2023-01-01", "2023-01-02", "2023-01-02", "2023-01-01",] ,
    "category": ["a", "b", 'a', 'b', 'a'] , 
    "value": [10, 20 , 30 , 40 , 50]})

pivot = df.pivot_table(index="date", columns = 'category', values = 'value', aggfunc='sum')
pivot

# category	a	b
# date		
# 2023-01-01	60	20
# 2023-01-02	30	40

 

 

심화

df = pd.DataFrame({
    "date": ["2023-01-01", "2023-01-01", "2023-01-02", "2023-01-02", "2023-01-01",] ,
    "category": ["a", "b", 'a', 'b', 'a'] , 
    "value": [10, 20 , 30 , 40 , 50] ,
    'subcategory': ['x', 'x', 'y', 'y', 'x']})

# index를 기준으로, 여러 컬럼 별로 나누고 합계 구하기
pivot = df.pivot_table(index = "date", columns = ['category', 'subcategory'], values = 'value', aggfunc = 'sum')
pivot

# category	a	b
# subcategory	x	y	x	y
# date				
# 2023-01-01	60.0	NaN	20.0	NaN
# 2023-01-02	NaN	30.0	NaN	40.0

 

 

데이터 정렬

df = pd.DataFrame({
    'name': ["Alice", "Bob", "Charlie", "David", "Eva"],
    'age' : [25, 22, 30 ,30, 18],
    'score': [85 , 88, 83, 90, 92]})
    
# 나이 컬럼으로 내림차순으로 정렬하기
df.sort_values(by="age", ascending = False)

# 여러 컬럼으로, 컬럼마다 다른 차순으로 정렬하기
df.sort_values(by=["age", "score"], ascending = [True, False])

# 인덱스 역순으로 정렬하기
df.sort_index(ascending=False)