Pandas란?
Pandas(판다스)는 파이썬의 데이터 조작 및 분석을 위한 강력한 라이브러리입니다. 주로 데이터를 처리하고 분석하는 데 사용되며, 고수준의 자료구조와 다양한 데이터 조작 도구를 제공합니다. 주로 시계열 데이터나 표 형태의 데이터를 다루는 데 유용합니다.
특징
- 데이터 구조: Series(1차원 배열)와 DataFrame(2차원 표 형태의 데이터 구조)를 제공하여 데이터 조작이 용이합니다.
- 데이터 조작: 누락된 데이터 처리, 데이터 필터링, 그룹화, 병합, 피벗 등 다양한 데이터 조작이 가능합니다.
- 데이터 시각화: Matplotlib와 함께 사용하여 데이터 시각화를 수행할 수 있습니다.
- 데이터 입출력: 다양한 파일 형식(CSV, Excel, JSON 등)에서 데이터를 읽고 쓰는 기능을 제공합니다.
기능
1. 데이터 구조 - Series 및 DataFrame 생성
- Series는 pd.Series()를 사용하여 생성하고, DataFrame은 pd.DataFrame()을 사용하여 생성합니다.
- 인덱스(Index)를 지정하여 데이터를 생성하고 접근합니다.
2. 데이터 조작
- 데이터 프레임에서 열을 선택하거나 조작하여 필요한 데이터를 추출합니다.
- 결측치 처리, 중복 제거, 데이터 타입 변환 등 데이터 정제 작업을 수행합니다.
- 그룹별 연산, 피벗 테이블, 병합(merge) 등의 데이터 조작 기능을 제공합니다.
3. 데이터 시각화
- Matplotlib 라이브러리와 함께 사용하여 데이터를 시각적으로 표현합니다.
- 그래프, 히스토그램, 산점도 등 다양한 차트와 플롯을 생성합니다.
4. 데이터 입출력
- CSV, Excel, JSON 등 다양한 파일 형식에서 데이터를 읽고 쓰는 기능을 제공합니다.
- SQL 데이터베이스와 연동하여 데이터를 읽고 쓰는 기능을 제공합니다.
코드 예시1
먼저 Pandas 라이브러리를 사용하여 데이터 조작 및 처리를 수행하는 코드를 보여드리겠습니다.
# pandas: 고수준의 자료구조(Series,DataFrame)을 지원
# 데이터 관리, 축약연산, 시계열 처리, 누락 데이터 처리, SQL 실행, SpreadSheet, 데이터 재배치, 시각화 등의 작업 수행 가능
# data munging, wrangling : 원 재료를 새로운 형태의 데이터로 전환하는 매핑 작업을 효율적으로 수행하도록 도와줌
import pandas as pd
from pandas import Series,DataFrame
import numpy as np
from statsmodels.sandbox.regression.tests.test_gmm import tvalues
#Series: 일련의 데이터(객체)를 담을수 있는 1차원 배열과 같은 구조로 색인을 갖는다. 인덱싱된 데이터의 1차원 배열!
obj=pd.Series([3,7,-5,5]) #리스트 타입- 순서 있음, 수정 가능
# obj=pd.Series((3,7,-5,5)) #튜플 타입-> 순서 있음, 수정 불가
# obj=pd.Series({3,7,-5,5}) #셋 타입 ->'set' type is unordered 에러가 떨어짐, 순서 없음->인덱싱할수 없다
print(obj,type(obj))
obj2=pd.Series([3,7,-5,5],index=['a','b','c','d'])
print(obj2,type(obj2))
print(obj2.sum(),sum(obj2),np.sum(obj2))
print(obj2.values) #[ 3 7 -5 5] - array를 반환하고 있다.
print(obj2.index)
#인덱싱/슬라이싱
print(obj2['a'])
print(obj2[['a']]) # a 인덱스가 가지고 있는 데이터 전체를 가지고 온다.
print(obj2[['a','b']])
print(obj2['a':'c'])
print(obj2[2])
print(obj2[1:4])
print(obj2[[2,1]]) #인덱싱 문자열이 있고, 숫자값이 유효하다.
print(obj2>0)
print('a' in obj2)
print('\n dict type : Series 객체로 처리')
names={'mouse':5000,'keyboard':25000,'monitor':550000}
print(names)
obj3=Series(names)
print(obj3,type(obj3))
obj3.index=['마우스','모니터','키보드']
print(obj3)
print(obj3[0],' ',obj3['마우스'])
obj3.name='상품가격'
print(obj3)
print('\nDataFrame : 표 모양-Series가 여러 개 합쳐진 형태')
df=DataFrame(obj3)
print(df,type(df))
data={
'irum':['홍길동','공기밥','김밥','주먹밥'],
'juso':['역삼동','신당동','신사동','신당동'],
'nai':[23,25,32,25],
}
print(data,type(data))
df2=pd.DataFrame(data)
print(df2,type(df2)) # dict타입의 키가 열의 이름이 된다. 각 열은 Series타입임.
print(df2.irum,type(df2.irum))
print()
print(DataFrame(data,columns=['juso','irum','nai']))
print('data에 없는 값을 주면 NAN으로 채움')
df3=DataFrame(data,columns=['juso','irum','nai','tel'],\
index=['a','b','c','d'])
print(df3)
df3['tel']='111-1111'
print(df3)
tvalue=Series(['222-2222','333-3333','444-4444'],index=['b','c','d'])
df3['tel']=tvalue
print(df3)
print('전치')
print(df3.T)
print(df3.values) #타입이 다 ndarray다.
print(df3.values[0,1]) # 인덱싱
print(df3.values[0:2]) # 슬라이싱
print('행 또는 열 삭제')
# df4=df3.drop(['d'])
df4=df3.drop(['d'],axis=0) # 행 삭제
print(df4)
#df4=df3.drop('te1',axis=1) # 열 삭제
#print(df4)
#정렬
print(df4.sort_index(axis=0,ascending=False)) #행 단위
print()
print(df4.sort_index(axis=1,ascending=True)) # 열이름 오름차순: irum juso nai, 내림차순: nai juso irum
print()
print(df4.rank(axis=0)) #사전순 순위를 매김
print()
counts=df4['juso'].value_counts()
print('열 값 갯수: ',counts)
print('문자열 자르기')
data={
'juso':['강남구 역삼동','중구 신당동','강남구 대치동'],
'inwon':[23,25,21]
}
fr=DataFrame(data)
print(fr)
result1=Series([x.split()[0] for x in fr.juso])
print(result1)
print(result1.value_counts())
result2=Series([x.split()[1] for x in fr.juso])
print(result2)
Series
Series는 1차원 배열과 유사한 데이터 구조로, 색인(index)을 가지는 데이터를 담을 수 있습니다.
- pd.Series(data): 데이터를 가지고 있는 Series 객체를 생성합니다.
주요 작업:
- 인덱싱/슬라이싱: obj['a'], obj['a':'c']와 같이 인덱스를 사용하여 데이터에 접근하거나 슬라이싱할 수 있습니다.
- 조건에 따른 필터링: obj2[obj2 > 0]와 같이 조건을 부여하여 데이터를 선택할 수 있습니다.
- 다양한 속성과 메서드: obj.values, obj.index, obj.sum() 등을 사용하여 데이터 및 속성에 접근하고 다양한 연산을 수행할 수 있습니다.
DataFrame
DataFrame은 표 형식의 데이터 구조로 여러 Series를 모아 행과 열을 가진 데이터를 표현합니다.
- pd.DataFrame(data): 데이터를 가지고 있는 DataFrame 객체를 생성합니다.
주요 작업:
- 열 및 행 선택: df['column_name'], df.loc['index_label']와 같이 열과 행에 접근할 수 있습니다.
- 열 추가/삭제: df['new_column'] = values와 같이 새로운 열을 추가하거나 df.drop()을 사용하여 열을 삭제할 수 있습니다.
- 데이터 정렬: df.sort_index(), df.sort_values()를 사용하여 데이터를 정렬할 수 있습니다.
- 결측값 다루기: df.dropna(), df.fillna()를 사용하여 결측값을 처리할 수 있습니다.
코드예시2
이를 활용하여 Pandas의 Series와 DataFrame을 활용하는 방법을 보여드리겠습니다.
# Reindexing, bool 처리, 인덱싱 지원 함수
from pandas import Series,DataFrame
# Series Reindexing
data=Series([1,3,2],index=(1,4,2))
print(data)
data2 = data.reindex((1,2,4)) #행 순서를 사용해 데이터 재배치
print(data2)
print('재배치할 때 값 끼워넣기')
data3=data2.reindex([0,1,2,3,4,5]) #대응 값이 없는 인덱스는 NaN(결치값)이 됨
print(data3)
# NaN을 임의의 값으로 채우기
data3=data2.reindex([0,1,2,3,4,5],fill_value=555)
print(data3)
print()
#NaN을 이전(앞) 행 값으로 채우기
data3=data2.reindex([0,1,2,3,4,5],method='ffill')
print(data3)
data3=data2.reindex([0,1,2,3,4,5],method='pad') #상동
print(data3)
print()
#NaN을 다음(뒤) 행 값으로 채우기
data3=data2.reindex([0,1,2,3,4,5],method='bfill')
print(data3)
data3=data2.reindex([0,1,2,3,4,5],method='backfill') #상동
print(data3)
print('bool 처리')
import numpy as np
df= DataFrame(np.arange(12).reshape(4,3),index=['1월','2월','3월','4월'],columns=['강남','강북','서대문'])
print(df)
print(df['강남'])
print(df['강남']>3)
print(df[df['강남']>3])
print('인덱싱 지원 함수 : Loc() - 라벨지원, iloc():숫자 지원')
print(df.loc['3월',:])
print(df.loc['3월',])
print(df.loc[:'2월'])
print(df.loc[:'2월',['서대문']])
print()
print(df.iloc[2])
print(df.iloc[2,:])
print(df.iloc[:3])
print(df.iloc[:3,2]) #3행미만 행 2열
print(df.iloc[:3,1:3]) #3행미만, 1,2열 출력
print('Series 연산')
s1=Series([1,2,3],index=['a','b','c'])
s2=Series([4,5,6,7],index=['a','b','d','c'])
print(s1)
print(s2)
print(s1+s2) #index명 불일치인 경우는 NaN
print(s1.add(s2)) # numpy 함수를 계승
print(s1*s2)
print(s1.mul(s2))
print('Series 연산')
df1=DataFrame(np.arange(9).reshape(3,3),columns=list('kbs'),index=['서울','대전','부산'])
df2=DataFrame(np.arange(12).reshape(4,3),columns=list('kbs'),index=['서울','대전','제주','수원'])
print(df1)
print(df2)
print(df1+df2)
print(df1.add(df2))
# -, *, / 가능 sub,mul,div
print()
print(df1)
seri=df1.iloc[0]
print(seri)
print(df1-seri) #DataFrame -Series
print()
#결측치 관련 함수(메소드)
df=DataFrame([[1.4,np.nan],[7,-4.5],[np.NaN,],[0.5,-1]],
columns=['one','two'])
print(df)
print(df.isnull())
print(df.notnull())
# print(df.drop(1)) #1행 삭제
print(df.dropna())
print(df.dropna(how='any'))
print(df.dropna(how='all'))
print(df.dropna(subset=['one'])) #특정 열에 NaN 있는 행 삭제
print(df.dropna(axis='rows'))
print(df.dropna(axis='columns'))
print()
print(df.fillna(0))
#기술 통계 관련 함수(메소드)
print(df)
print(df.sum())
print(df.sum(axis=0)) #열의 합, 상동
print(df.sum(axis=1)) #행의 합
print()
print(df.mean(axis=1))
print(df.mean(axis=1,skipna=True)) #NaN은 연산에서 제외
print(df.mean(axis=1,skipna=False))
print(df.mean(axis=0,skipna=True)) #열 단위
print()
print(df.describe()) #요약 통계량 출력
print(df.info()) #구조 출력
재배치(Reindexing)
- reindex() 메서드를 사용하여 데이터의 새로운 순서에 맞게 재배치하거나, 결측값을 다른 값으로 채울 수 있습니다.
- fill_value, method 옵션을 사용하여 NaN(결측값)을 채우는 방법을 설정할 수 있습니다.
불리언 처리(Boolean Handling)
- 조건을 활용하여 DataFrame의 데이터를 필터링할 수 있습니다. 예를 들어, df[df['강남'] > 3]와 같이 조건을 부여하여 특정 조건을 만족하는 행을 선택할 수 있습니다.
인덱싱 지원 함수
- loc[]: 라벨(label)을 사용하여 데이터에 접근합니다.
- iloc[]: 숫자를 사용하여 데이터에 접근합니다.
Series 및 DataFrame 연산
- 서로 다른 인덱스를 가진 Series를 연산할 때, 인덱스가 일치하지 않는 부분은 NaN으로 처리됩니다.
- DataFrame 간의 연산도 가능하며, 서로 일치하지 않는 위치에서는 NaN으로 처리됩니다.
결측치 관련 함수
- isnull(), notnull(): 데이터가 결측치인지 아닌지를 확인합니다.
- dropna(): 결측치를 포함하는 행 또는 열을 제거합니다.
- fillna(): 결측치를 다른 값으로 대체합니다.
기술 통계량 관련 함수
- sum(), mean(), describe(): 데이터의 합, 평균, 요약 통계량을 계산합니다.
- info(): DataFrame의 구조를 출력합니다.
# DataFrame : reshape, cut, merge
import numpy as np
import pandas as pd
df=pd.DataFrame(1000+np.arange(6).reshape(2,3),index=['대전','서울'],columns=['2021','2022','2023'])
print(df)
df_row=df.stack() #재구조화 열 -> 행으로 변환 ->칼럼 쌓기
print()
print(df_row)
print()
df_col=df_row.unstack() #행 ->열로 변환
print(df_col)
print()
print('범주화 : 연속형 자료를 범주형으로 변경')
price=[10.3,5.5,7.8,3.6]
cut=[3,7,9,11] #구간 기준값
result_cut=pd.cut(price,cut)
print(result_cut) #(9, 11] : 9초과 11이하 9 < x <= 11
print()
print(pd.value_counts(result_cut))
print()
datas=pd.Series(np.arange(1,1001))
print(datas.head(3))
print(datas.tail(3))
print()
result_cut2 = pd.qcut(datas,3) #datas 값을 3개 영역으로 범주화
print(result_cut2)
print()
print(pd.value_counts(result_cut2))
print()
cut2=[1,500,1000]
result_cut3 =pd.cut(datas,cut2)
print(result_cut3)
print()
print(pd.value_counts(result_cut3))
print()
print('그룹별 함수 수행 : agg,apply')
group_col=datas.groupby(result_cut2)
print(group_col.agg(['count','mean','std','max']))
print()
#agg 대신 함수 직접 작성
def summary_fuc(gr):
return {
'count':gr.count(),
'mean':gr.mean(),
'std':gr.std(),
'max':gr.max(),
}
print(group_col.apply(summary_fuc)) #apply->함수를 실행하는 것
print(group_col.apply(summary_fuc).unstack())
print()
print('\n병합(merge)')
df1=pd.DataFrame({'data1':range(7),'key':['b','b','a','c','a','a','b']})
print(df1)
print()
df2=pd.DataFrame({'key':['a','b','d'],'data2':range(3)})
print(df2)
print()
print(pd.merge(df1,df2)) #key를 기준으로 inner join
print()
print(pd.merge(df1,df2,on='key',how='inner')) #key를 기준으로 inner join, 상동
print()
print(pd.merge(df1,df2,on='key',how='outer')) #key를 기준으로 outer join
print()
print(pd.merge(df1,df2,on='key',how='left')) #key를 기준으로 left outer join
print()
print(pd.merge(df1,df2,on='key',how='right')) #key를 기준으로 right outer join
print()
print('공통 칼럼이 없는 경우 : df1 vs df3')
print()
df3=pd.DataFrame({'key2':['a','b','d'],'data2':range(3)})
print(df3)
print()
print(pd.merge(df1,df3,left_on='key',right_on='key2'))
print()
print('\nDataFrame 자료 이어붙이기')
print(pd.concat([df1,df3],axis=0)) #행 단위- default
print()
print(pd.concat([df1,df3],axis=1)) #열 단위
print()
print('Series 병합')
s1=pd.Series([0,1],index=['a','b'])
s2=pd.Series([2,3,4],index=['c','d','e'])
s3=pd.Series([5,6],index=['f','g'])
print(pd.concat([s1,s2,s3],axis=0))
DataFrame Reshape
- stack(): 열을 행으로 변환하여 쌓는 작업을 수행합니다.
- unstack(): 행을 열로 변환하는 작업을 수행합니다.
범주화(Cut)
- pd.cut(): 연속형 자료를 구간별로 나누어 범주형으로 변환합니다.
- pd.qcut(): 데이터 값을 기준으로 지정된 개수의 구간으로 나눕니다.
데이터 합치기(Merge)와 이어붙이기(Concat)
- pd.merge(): 두 DataFrame을 병합합니다. on, how 등의 옵션을 사용하여 특정 열이나 병합 방법을 지정할 수 있습니다.
- pd.concat(): DataFrame을 이어붙입니다. axis를 사용하여 행 또는 열로 이어붙일 수 있습니다.
++ Pandas는 데이터 과학 분야에서 핵심적인 역할을 하는 파이썬 라이브러리로, 데이터를 처리하고 분석하는 데 필수적이라고 할수 있습니다. 또한, 데이터 전처리, 정제, 조작, 통계 분석, 시각화 등 다양한 작업을 지원하여 데이터 기반 의사 결정 및 머신러닝 모델 개발에 활용되기에, 데이터 과학가나 엔지니어들이 데이터를 처리하고 분석할 때 Pandas는 강력한 도구로 쓰입니다.