본문 바로가기
IT & 데이터 사이언스/Python

[Python Data Analytics] Pandas를 활용한 데이터 조작(2)

by 바른 호랑이 2023. 6. 17.
728x90
반응형

※ Pandas를 활용한 데이터 조작 

 

[Python Data Analytics] Pandas를 활용한 데이터 조작(1)

안녕하세요. 바른 호랑이입니다. 이번 게시글에서는 Python 데이터 분석의 기초라 할 수 있는 Pandas를 활용한 데이터 분석 방법에 대해 알아볼 계획입니다. 데이터 분석 업무는 데이터를 수집하고

data-is-power.tistory.com

안녕하세요. 바른 호랑이입니다.

이번 게시글에서는 저번 게시글에 이어서 Python의 데이터 분석을 위해 사용되는 Open source Library인 Pandas를 활용한 데이터 조작방법에 대해 알아볼 예정입니다.

이전 게시글에서 대표적인 자료구조와 해당 자료구조의 간단한 조작방법에 대해서 알아본 것에 이어서 이번에는 정렬과 연산에 대해서 알아볼 예정입니다. 이번에도 Colab을 활용하여 복잡한 환경설정없이 실습을 진행할 예정이며, Colab에 대해서 보다 자세한 정보가 궁금하신 분들은 아래의 사이트를 참조하시면 되겠습니다. 

 

Google Colaboratory

 

colab.research.google.com

※ 실습파일

Python_DataAnalysis_02(Pandas).ipynb
0.02MB

# Pandas 설치
!pip install pandas

# Pandas 로드
import pandas as pd

# 테이블 생성
exam_result = {
                'Name' : ['John', 'Anne', 'Jacob']
              , 'Math' : [90, 75, 100]
              , 'English' : [100, 80, 95]
              , 'Music' : [80, 100, 60]
              , 'Athletic' : [80, 70, 85]
              }
df = pd.DataFrame(exam_result)

# 특정 열을 행 인덱스로 설정
df1 = df.copy()
df2 = df.copy()
df3 = df.copy()

df1.set_index(['Name'], inplace=True)
df2.set_index(['Math'], inplace=True)
df3.set_index(['Music'], inplace=True)

# 결과 출력
print(f'{df}\n\n{df1}\n\n{df2}\n\n{df3}')

# 행 인덱스 재배열
new_index = [i for i in range(5)]
ndf = df.reindex(new_index)
ndf2 = df.reindex(new_index, fill_value=0)

# 결과 출력
print(f'{df}\n\n{ndf}\n\n{ndf2}')

# 행 인덱스 초기화
ndf3 = df.reset_index()

print(f'{df}\n\n{ndf3}')

# 행 인덱스 기준으로 데이터 프레임 정렬
ndf4 = df.sort_index() # 기본 정렬 default는 ascending(오름차순)
ndf5 = df.sort_index(ascending=False) # 내림차순 적용 

print(f'{ndf4}\n\n{ndf5}')

# 열 기준 정렬
ndf6 = df.sort_values(by=['Math', 'English']) # by 옵션으로 기준열 지정 / 복수 지정 가능
ndf7 = df.sort_values(by='Math', ascending=True)

print(f'{ndf6}\n\n{ndf7}')

# 산술연산
''' 
* 시리즈 연산
- 시리즈와 숫자의 연산 
사칙연산이 기본적으로 가능하며, 모든 원소들에 각각 연산이 들어가는 형태로 계산됨.
- 시리즈와 시리즈의 연산
사칙연산이 기본적으로 가능하며, 각 시리즈의 인덱스를 기준으로 같은 인덱스를 가진 값들이 서로 매칭되어 계산됨.
만약 연산을 하는 두 시리즈의 원소의 개수, 인덱스 값이 다르면 정상적인 연산이 불가능하며, 이때 매칭되지 않은 값들은
NaN으로 처리됨. 만약 값이 모두 존재하여 매칭이 된다해도 한 쪽의 값이 NaN이면 결과가 NaN으로 입력됨.
'''
# 시리즈 생성
student = pd.Series({'Korean' : 90, 'Math' : 85, 'English' : 95})
addition = student+5
subtraction = student-5
multiplication = student*2
division = student/2

# print문 사용시 코드가 길어서 가독성을 위해 줄바꿔서 표기하고 싶으면 줄바꾸는 위치에 백슬래쉬(\)를 써서 적용가능
print(
      f'--------------------------------------------------------------------------------\
      \n{student}\n\n{addition}\n\n{subtraction}\n\n{multiplication}\n\n{division}\
      \n--------------------------------------------------------------------------------'
     )

# 추가 시리즈 생성
student2 = pd.Series({'Korean' : 80, 'Math' : 100, 'English' : 90})
addition2 = student+student2
subtraction2 = student-student2
multiplication2 = student*student2
division2 = student/student2

print(
      f'--------------------------------------------------------------------------------\
      \n{addition2}\n\n{subtraction2}\n\n{multiplication2}\n\n{division2}\
      \n--------------------------------------------------------------------------------'
     )

# 계산결과를 데이터프레임으로 합치기
result = pd.DataFrame(
                      [addition2, subtraction2, multiplication2, division2]
                    , index=['addition', 'subtraction', 'multiplication', 'division']
                    , columns=['Korean', 'Math', 'English'] 
                     )

print(
      f'--------------------------------------------------------------------------------\
      \n{result}\
      \n--------------------------------------------------------------------------------'
     ) 
     
 # NaN 처리를 위한 추가 패키지 설치시
!pip install numpy

# 필요 패키지 로드
import numpy as np

# NaN이 있는 시리즈 연산
# NaN : 유효한 값이 존재하지 않는다는 의미
# 시리즈 생성
student1 = pd.Series({'Korean' : 90, 'Math' : 85, 'English' : 100})
student2 = pd.Series({'Korean' : 80, 'Math' : 100, 'English' : np.nan})

addition3 = student1+student2
subtraction3 = student1-student2
multiplication3 = student1*student2
division3 = student1/student2

print(
      f'--------------------------------------------------------------------------------\
      \n{addition3}\n\n{subtraction3}\n\n{multiplication3}\n\n{division3}\
      \n--------------------------------------------------------------------------------'
     )

# 연산 메소드를 활용하여 NaN값 채워넣기
'''
Pandas에서 제공하는 사칙연산 메소드
add : 덧셈
sub : 뺄셈
mul : 곱셈
div : 나눗셈
'''
addition4 = student1.add(student2, fill_value=0)
subtraction4 = student1.sub(student2, fill_value=0)
multiplication4 = student1.mul(student2, fill_value=0)
division4 = student1.div(student2, fill_value=0)

print(
      f'--------------------------------------------------------------------------------\
      \n{addition4}\n\n{subtraction4}\n\n{multiplication4}\n\n{division}\
      \n--------------------------------------------------------------------------------'
     )
     
 '''
* loc와 iloc로 추출할때 유의사항
- loc는 로우와 컬럼의 이름으로 추출하며 양끝단의 데이터를 모두 포함하게 됨.
- iloc는 로우와 컬럼의 인덱스 번호로 추출하며 마지막 단의 데이터는 추출하지 않음
- dataframe.loc[0:1, :]과 dataframe.iloc[0:1, :]은 값이 다르게 출력됨.
'''
df = pd.DataFrame([[0, 0, 0], [1, 1, 1], [2, 2, 2]], columns=[0, 1, 2])
print(
      f'--------------------------------------------------------------------------------\
      \n{df.loc[0:1, :]}\n\n{df.iloc[0:1, :]}\
      \n--------------------------------------------------------------------------------\
      \n{df.loc[:, 0:1]}\n\n{df.iloc[:, 0:]}\
      \n--------------------------------------------------------------------------------'
     )
     
 ''' 
* 데이터프레임 연산
- 데이터프레임과 숫자의 연산 
사칙연산이 기본적으로 가능하며, 모든 원소들에 각각 연산이 들어가는 형태로 계산됨.
- 데이터프레임와 데이터프레임의 연산
사칙연산이 기본적으로 가능하며, 각 데이터프레임의 인덱스를 기준으로 같은 인덱스를 가진 값들이 서로 매칭되어 계산됨.
만약 연산을 하는 두 데이터프레임의 원소의 개수, 인덱스 값이 다르면 정상적인 연산이 불가능하며, 이때 매칭되지 않은 값들은
NaN으로 처리됨. 만약 값이 모두 존재하여 매칭이 된다해도 한 쪽의 값이 NaN이면 결과가 NaN으로 입력됨.
'''
# 간편하게 사용할 수 있는 대표적인 데이터를 다운로드
import seaborn as sns
titanic = sns.load_dataset('titanic')

# head함수로 데이터 값을 간단하게 확인가능 따로 파라미터를 주지 않으면 5개행만 출력
print(
      f'--------------------------------------------------------------------------------\
      \n{titanic.head(10)}\
      \n--------------------------------------------------------------------------------'
     )

# 필요한 컬럼만 추출
ext_ttc = titanic.loc[:, ['age', 'fare']]
add = ext_ttc.head() + 5
sub = ext_ttc.head() - 5
mul = ext_ttc.head() * 5
div = ext_ttc.head() / 5

print(
      f'--------------------------------------------------------------------------------\
      \n{add}\n\n{sub}\n\n{mul}\n\n{div}\
      \n--------------------------------------------------------------------------------'
     )
     
 ext_ttc_01 = ext_ttc.iloc[:6, :].fillna(0)
ext_ttc_02 = ext_ttc.iloc[6:12, :].reset_index(drop=True).fillna(0)
'''
* 유의사항
데이터 프레임 연산을 위한 인덱스를 맞춰줄 때에는 반드시 로우와 컬럼의 인덱스를 동일한 이름으로
맞춰줘야 연산이 가능함. 위의 경우에 있어서 reset_index를 안하게 되면 로우의 인덱스 명이 0~5, 6~10으로
차이가 나게되어 전부 NaN으로 표기됨. reset_index 사용시 drop=True옵션을 주게되면 자동으로 기존의 인덱스
컬럼은 삭제되게됨. fillna함수를 사용하여 결측값들을 특정값으로 대체할 수 있음.
'''
add2 = ext_ttc_01 + ext_ttc_02
sub2 = ext_ttc_01 - ext_ttc_02
mul2 = ext_ttc_01 * ext_ttc_02
div2 = ext_ttc_01 / ext_ttc_02

print(
      f'--------------------------------------------------------------------------------\
      \n{add2}\n\n{sub2}\n\n{mul2}\n\n{div2}\
      \n--------------------------------------------------------------------------------'
     )

P.S 더 나은 개발자가 되기위해 공부중입니다. 잘못된 부분을 댓글로 남겨주시면 학습하는데 큰 도움이 될 거 같습니다.

728x90
반응형

댓글