머신러닝

판다스 (Pandas) : 파이썬의 대표적인 데이터 처리 패키지

jeongpil 2021. 3. 9. 12:36

*해당 포스팅은 파이썬 머신러닝 완벽 가이드(권철민 지음) 교재를 공부하며 작성한 글입니다.

 

 

이전 글에서 머신러닝 개발을 위해 이해해야 할 중요 요소인 넘파이와 판다스 중 넘파이를 알아봤습니다.

 

이번 포스팅에서는 파이썬의 대표적인 데이터 처리 패키지인 판다스에 대해 알아보겠습니다.

 

 

1. 판다스란?

2. 데이터프레임과 리스트, 딕셔너리, 넘파이 ndarray 상호 변환

  2-1. 리스트, 딕셔너리, ndarray -> 데이터프레임

  2-2. 데이터프레임 -> 리스트, 딕셔너리, ndarray

3. 판다스로 데이터프레임 다루기

  3-1. 칼럼 데이터 세트 생성과 수정

  3-2. 데이터 삭제

  3-3. 데이터 선택 및 필터링

  3-4. 데이터 정렬, Aggregation함수, GroupBy

4. 판다스로 결손 데이터 처리하기

 

 

1. 판다스란?

 

판다스는 파이썬에서 데이터 처리를 위해 존재하는 가장 인기 있는 라이브러리입니다.

 

넘파이가 1차원 배열 처리를 돕는 것과 다르게 판다스는 2차원 데이터를 효율적으로 다룰 수 있게 도와줍니다.

 

판다스를 이용하면 데이터를 불러오는 것부터 데이터를 전처리하는 것까지 쉽게 할 수 있습니다.

 

 

판다스의 핵심 객체는 여러 개의 행과 열로 이루어진 2차원 데이터를 담는 데이터 구조체인 데이터프레임입니다.

 

데이터프레임을 이해하기 전에 다른 중요 객체인 Index와 Series를 이해하는 것도 중요합니다.

 

Index란 개별 데이터를 고유하게 식별하는 key값이고 Series는 칼럼이 하나뿐인 데이터 구조체입니다.

 

 

 

2. 데이터프레임과 리스트, 딕셔너리, 넘파이 ndarray 상호 변환

2-1. 리스트, 딕셔너리, ndarray -> 데이터프레임

 

col_names=['A','B','C']
list=([1,2,3],[2,4,6])
array=np.array(list)
dict={'A':[1,2],'B':[2,4],'C':[3,6]}

df_list=pd.DataFrame(list,columns=col_names)  # list -> DataFrame
df_array=pd.DataFrame(array,columns=col_names) # array -> DataFrame
df_dict=pd.DataFrame(dict) #  dictionary -> DataFrame

display(df_list)
display(df_array)
display(df_dict)

 

 

2-2. 데이터프레임 -> 리스트, 딕셔너리, ndarray

 

많은 머신러닝 패키지가 기본 데이터 형으로 넘파이 ndarray를 사용하기 때문에

 

머신러닝 패키지의 입력 인자 등에  적용하기 위해 데이터프레임을 넘파이 ndarray로 변환하는 경우가 빈번하게 발생합니다.

 

list=df_list.values.tolist() # DataFrame -> list
array=df_array.values # DataFrame -> array
dict=df_dict.to_dict('list') # DataFrame -> dictionary

display(list)
print('타입 :',type(list))
display(array)
print('타입 :',type(array))
display(dict)
print('타입 :',type(dict))

 

 

3. 판다스로 데이터프레임 다루기

3-1. 칼럼 데이터 세트 생성과 수정

 

df_people=pd.DataFrame({'이름':['민호','철수','영희','민아'],'나이':[20,27,35,25]}) # 데이터프레임 생성
display(df_people) # 기본 데이터프레임

df_people['주소']=None # 주소 칼럼 생성
display(df_people)

df_people['주소']='서울특별시' # 칼럼 데이터 수정
display(df_people)

 

 

3-2. 데이터 삭제

 

데이터프레임에서 데이터 삭제는 drop()을 이용합니다. 

 

drop()에서 중요한 파라미터는 labels, axis, inplace 입니다

 

- labels : 칼럼

 

- axis : aixs0은 로우 방향, axis1은 칼럼 방향

 

- inplace : True면 원본데이터 바뀌고 None 반환, False면 원본데이터 변하지 않고 결과 반환

 

 

※ inplace=True이면 반환 값이 None이므로 반환 값을 자신의 DataFrame에 할당하면 안 됨.

 

display(df_people)
df_people_drop_axis0=df_people.drop([0,1],axis=0) # 로우 삭제, []내에 인덱스값
display(df_people_drop_axis0) # 삭제된 반환값

 

display(df_people) #원본 데이터프레임

# 칼럼삭제, 원본 데이터프레임 유지, 결과 df 반환
df_drop_inplace_False=df_people.drop('주소',axis=1,inplace=False) 
display(df_drop_inplace_False) #반환값
display(df_people) #원본 데이터프레임

# 칼럼삭제, 원본 데이터프레임 변화, 반환값 None
df_drop_inplace_True=df_people.drop('주소',axis=1,inplace=True) 
display(df_drop_inplace_True) #반환값
display(df_people) #원본 데이터프레임

 

 

3-3. 데이터 선택 및 필터링

 

① [ ] 연산자

 

넘파이의 [ ]연산자의 경우 행의 위치, 열의 위치, 슬라이싱 범위 등을 지정해 데이터를 가져올 수 있었지만

 

데이터프레임에서 [ ]안에 들어갈 수 있는 것은 칼럼을 지정할 수 있는 것들만 들어갈 수 있습니다.

 

칼렴 명 문자 또는 인덱스로 변환 가능한 표현식이 가능합니다.

 

df_people=pd.DataFrame({'이름':['민호','철수','영희','민아'],'나이':[20,27,35,25],
                        '주소':['강남구','용산구','중구','송파구'],
                        '성별':['Male','Male','Female','Female']}) # 데이터프레임 생성
display(df_people)
display(df_people['이름']) # 이름 칼럼 데이터 추출
dispaly(df_people[0]) # 넘파이와 다르게 숫자index는 KeyError 발생

 

 

 

② loc[ ] 연산자

 

loc[ ]은 명칭 기반으로 데이터를 추출합니다.

 

loc[ ]에서 슬라이싱 기호인 ':'은 종료 값까지 포함합니다.

 

명칭 기반이기 때문에 -1을 할 수가 없기 때문입니다.

 

display(df_people) # 인덱스가 1,2,3,4 인 데이터프레임으로 변환

# 인덱스가 1이고 컬럼명이 이름인 데이터 추출
display(df_people.loc[1,'이름'])

# 인덱스가 1부터 2이고 컬럼명이 주소인 데이터 추출
display(df_people.loc[1:2,'주소']) 

# 인덱스가 1부터 2이고 컬렴명이 주소부터 성별인 데이터 추출
display(df_people.loc[1:2,'주소':'성별'])

#인덱스가 1, 3이고 컬렴명이 이름, 주소인 데이터 추출 (팬시 인덱싱)
display(df_people.loc[[1,3],['이름','주소']])

 

 

 

③ iloc[ ] 연산자

 

iloc[ ]은 위치 기반으로만 데이터를 추출합니다.

 

위치 기반 인덱싱만 허용되기 때문에 불린 인덱싱은 iloc[ ]에서 제공되지 않습니다.

 

display(df_people)
display(df_people.iloc[1,1])# 2번째 행, 2번째 열 데이터 추출
display(df_people.iloc[0:2,0:2]) # 0에서 1번째 행, 0에서 1번째 열 데이터 추출
display(df_peole.iloc[0,'이름']) # '이름' 때문에 ValueError 발생

 

 

 

④ 불린 인덱싱

 

and 조건일 때는 & , or 조건일 때는 | , not 조건일 때는 ~ 를 사용합니다.

 

display(df_people)

# 나이가 30미만이고 강남구에 사는 사람 추출
display(df_people[(df_people['나이']<30)&(df_people['주소']=='강남구')])

# 나이가 30초과이거나 강남구에 사는 사람 추출
display(df_people[(df_people['나이']>30)|(df_people['주소']=='강남구')])

 

 

3-4. 데이터 정렬, Aggregation 함수, GroupBy

 

① 정렬

 

데이터프레임과 Series의 정렬을 위해서는 sort_values()를 이용합니다. 

 

ascending=True이면 오름차순, ascending=False이면 내림차순으로 정렬합니다.

 

display(df_people)

df_people_asc=df_people.sort_values(by=['나이'],ascending=True) #  나이 오름차순
display(df_people_asc)

df_people_desc=df_people.sort_values(by=['나이'],ascending=False) # 나이 내림차순
display(df_people_desc)

 

 

 

② Aggregation 함수

 

데이터프레임에서 바로 min(), max(), avg(), sum(), count()와 같은 aggregation 함수를 호출할 경우 모든 칼럼에 해당 aggregation이 적용됩니다.

 

특정 칼럼에 aggregation 함수를 적용하기 위해서는 특정 칼럼들만 추출해 적용하면 됩니다.

 

display(df_people)
display(df_people.count()) # 전체 칼럼에 count 적용
display(df_people[['이름','나이']].count()) # 이름, 나이 칼럼에 count 적용

 

 

 

③ GroupBy

 

groupby() 사용 시 입력 파라미터 by에 칼럼을 입력하면 대상 칼럼이 기준이 되어 묶이게 됩니다.

 

display(df_people)
df_people_groupby=df_people.groupby(by='성별') # 성별로 groupby
display(df_people_groupby['나이'].sum()) # 성별 별 나이의 합
display(df_people_groupby['나이'].agg([max,min])) # 성별 별 나이 최대, 최소 값

 

 

4. 판다스로 결손 데이터 처리하기

 

결손 데이터는 NaN으로 표기되며 결손 데이터 여부를 확인하는 API는 isna() 이고

 

NaN값을 다른 값으로 대체하는 API는 fillna() 입니다.

 

df_people['학점']=[None,3.4,3.8,4.2] #학점 칼럼 추가 NaN 데이터 포함
display(df_people)
display(df_people.isna()) # 결측치 확인
display(df_people.isna().sum()) # 결측치 갯수 확인
df_people.fillna(df_people['학점'].mean(), inplace=True)# 학점 결측치를 나머지 학생들의 평균 학점 값으로 대체
display(df_people)

 

 

 

이상 판다스를 활용하여 데이터프레임을 다루는 법에 대해 알아봤습니다.

 

넘파이와 판다스는 범위가 매우 넓기 때문에 공부하고 포스팅한 부분은 매우 일부에 불과합니다.

 

 

저는 앞으로 직접 프로그램을 짜 보면서 더 많은 부분에 대해 공부해 나갈 것입니다.

 

직접 데이터를 데이터프레임 형태로 만들어보고 추가, 수정, 원하는 데이터를 추출하는

 

과정을 해보니 너무 재밌고 앞으로 더욱 큰 데이터를 다뤄보고 싶어졌습니다 : )