데이터 분석 - Pandas 기초

LSH·2023년 5월 25일
0

교육 정보

  • 교육 명: 경기미래기술학교 AI 교육
  • 교육 기간: 2023.05.08 ~ 2023.10.31
  • 오늘의 커리큘럼: 빅데이터 기초 활용 역량 강화 (5/10~6/9) - 데이터 분석
  • 강사: 조미정 강사님 (빅데이터, 머신러닝, 인공지능)
  • 강의 계획:
    1. 파이썬 언어 기초 프로그래밍
    2. 크롤링 - 데이터 분석을 위한 데이터 수집(파이썬으로 진행)
    3. 탐색적 데이터 분석, 분석 실습
    - 분석은 파이썬만으로는 할 수 없으므로 분석 라이브러리/시각화 라이브러리를 통해 분석
    4. 통계기반 데이터 분석
    5. 미니프로젝트

1. Pandas

1.1 Pandas의 개념

  • 파이썬 데이터 처리에서 가장 인기 있는 라이브러리
  • 2차원 데이터를 효율적으로 가공/처리 할 수 있는 기능들을 제공
  • 주요 개념들
    • index : RDBMS의 PK처럼 개별 데이터를 고유하게 식별하는 key값
    • Serise : 칼럼이 하나뿐인 구조체
    • DataFrame : 2차원 데이터 구조체, 여러개의 Serise 로 이루어져있음

1.2 Pandas 기본 문법

https://pandas.pydata.org/pandas-docs/stable/user_guide/10min.html
공식에서 제공하는 유저 가이드

✏️ import

import pandas as pd
# 일반적으로 pd로 많이 불러옴

✏️ 파일 읽어오기

titanic_df = pd.read_csv("/content/titanic.csv")
# 경로를 지정하여 파일을 읽어와서 변수에 저장

✏️ 시리즈 생성

  • series = index + value
s= pd.Series(['a','b','c'])
print(s)
#
# 결과
0    a
1    b
2    c
dtype: object

✏️ 데이터 프레임 생성

  • DataFrame = index + value + "columns"
df1 = pd.DataFrame([1,2,3,4])
print(df1)
#
# 결과
   0
0  1
1  2
2  3
3  4
  • 다중리스트 사용
lista = [[1,2,3],[4,5,6]]
df2 = pd.DataFrame(lista)
print(df2)
df3 = pd.DataFrame(lista, columns = ['col1', 'col2', 'col3'])
print(df3)
#
# 결과
   0  1  2
0  1  2  3
1  4  5  6
   col1  col2  col3
0     1     2     3
1     4     5     6
  • 딕셔너리 사용
dict1 = {'col1':[1,2,3,4,5],'col2':[5,6,7,8,9]}
df4 = pd.DataFrame(dict1)
print(df4)
#
# 결과
col1	col2
0	1	5
1	2	6
2	3	7
3	4	8
4	5	9

✏️ Column

  • 열 추출: df[컬럼명]
  • 열 생성: df[새로 만들 컬럼명] = Value
  • 열 수정: df[수정할 컬럼명] = 수정할 Value
titanic_df[["Pclass","Survived"]]
#열 추출
titanic_df['Age_0']=0
#열 생성
titanic_df['Age_0'] = titanic_df['Age']*10
#열 수정

✏️ 데이터 삭제

# 데이터프레임.drop('컬럼명', axis = 0)
axis 옵션이 0이면 행, 1이면 열(default = 0) -> 애가 행인지 열인지 구분을 못해서 지정해줘야 함
print(titanic_df.shape)
titanic_df.drop("Age_0", axis=1)
# 해당 데이터를 삭제한 데이터 프레임을 리턴하지만 원본에서 삭제하는것은 아님
# →칼럼을 원본 데이터 프레임에서 삭제 하는 방법
# 1. inplace 옵션을 True로 줌
titanic_df.drop("Age_0", axis = 1, inplace=True)
# 2. 원본 데이터프레임에 재 할당 
titanic_df = titanic_df.drop("Age_0", axis = 1)

✏️ 데이터 선택(iloc) - 위치기반

  • iloc[행인덱스, 열인덱스] 연산자 (함수가 아니라 연산자임, 대괄호 사용)
  • 위치 기반 인덱싱만 허용
  • 행과 열 값으로 integer형만 허용
titanic_df.iloc[0:5]
#인덱스의 value를 참조하지 않고 위치로 참조한것
titanic_df.iloc[0:5, 1]
#하나만 할거면 이렇게도 되고
titanic_df.iloc[0:5, 0:3]
#두개이상 할거면 슬라이싱
titanic_df.iloc[[1,2,3,6], [1,3,5]] 
#이어져있지 않은 여러개의 행 혹은 열을 조회하고 싶을때는 하나의 데이터로 (리스트로)만들어서 넣어주면 됨 

✏️ 데이터 선택(loc) - 인덱스값(이름) 기반

  • loc[행조건, 열조건] ❗️하나만 넣으면 행조건이 기본
  • 명칭 기반 데이터 추출 (위치기반인 iloc이랑 다름)
  • 행 위치에는 DataFrame index 값을, 열 위치에는 컬럼명을 입력
titanic_df.loc[4]
# 인덱스 값이 4인 행 출력
titanic_df.loc[0:11, ['Age','Name']]
# 인덱스 0~11, column 지정
titanic_df.loc[5,'Name']
# 행 인덱스가 5이고 열 인덱스는 'Name'인 값을 출력

✏️ 데이터선택 - 조건

# 승객 중 나이(Age)가 65세 이상인 데이터를 추출
titanic_df['Age']>=65
# 내가 건 조건에 대해 True False 리턴
titanic_df[titanic_df['Age']>=65]
# 내가 건 조건에 대해 True인 **값**을 리턴 
titanic_df.loc[titanic_df['Age']>=65,["Name","Age"]]
# 내가 건 조건에 대해 True인 행에서 'Name', 'Age'값을 리턴 
  • 여러 조건을 가지는 경우
여러 조건을 가지는 경우 조건은 ()안에 작성
titanic_df[(titanic_df['Age']>=60) & (titanic_df['Sex']=='female') & (titanic_df['Pclass']==1)]
# 혹은 조건들을 변수에 할당
con1=titanic_df['Age']>=60
con2=titanic_df['Sex']=='female'
con3=titanic_df['Pclass']==1
titanic_df[con1 & con2 & con3]
  • 특정 값을 지정하고 싶은 경우 isin()
print(titanic_df[titanic_df['Embarked'].isin(["S", "C"])])
# 값이 S, C인 항목 출력

✏️ sort_values

titanic_df.sort_values("Fare",ascending = False)
# Fare 컬럼을 참조하여 정렬
titanic_df.sort_values(["Pclass", "Name"], ascending =[True, False])
# 여러개의 컬럼을 참조하여 정렬

✏️ Aggregation 함수 적용

  • min(), max(), sum(), count()
titanic_df.count()
# 모든 컬럼의 카운트 (None 제외)
titanic_df["Age"].count()
# 컬럼 지정하여 카운트
titanic_df[['Age','Fare']].mean()
# 컬럼의 평균을 출력. 
titanic_df[["Age","Fare"]].median()
# 중간값 출력
titanic_df["Embarked"].unique()
# 중복제거한 값 출력

✏️ groupby() 적용

titanic_grouped = titanic_df.groupby("Pclass")
# 반환된 결과에 aggregation 함수를 호출하면 다른 모든 칼럼에 aggregation 함수 적용
titanic_df.groupby("Pclass").count()
# 특정 칼럼만 적용하려면 DataFrameGroupBy 객체에 해당 칼럼을 필터링한 뒤 aggregation함수 적용
titanic_df.groupby("Pclass")[["Age", "Name"]].count()
# 여러 aggregation 함수를 사용할 경우 
# DataFrameGroupBy 객체에 agg() 를 적용해 동일하게 구현 
titanic_df.groupby('Pclass').agg("count")
# titanic_df.groupby("Pclass").count() 이 코드와 동일! 
# 컬럼 지정도 가능
titanic_df.groupby('Pclass')[["Age", "Fare"]].agg("count")
titanic_df.groupby('Pclass').agg("count")
titanic_df.groupby("Pclass").count()
# 위 두 코드가 같으면 agg는 왜 쓰는가?
#적용하고자 하는 함수가 여러개일떄 리스트로 여러개의 함수를 적용 할 수 있다.
titanic_df.groupby('Pclass')["Age"].agg(['count','min', 'max', 'mean'])
# agg() 내에 입력값으로 딕셔너리 형태로 aggregation이 적용될 칼럼들과 함수 입력
# -> 각각의 함수를 어디 컬럼에 적용할지 지정 하겠다
agg_format = {'Age':'max', 'SibSp':'sum', 'Fare':'mean'}
titanic_df.groupby('Pclass').agg(agg_format)
# 여러 aggregation 함수를 사용할 경우 
#'Pclass'로 그룹하고 'Age'컬럼에 대해서 'max','min','mean','sum'을 모두 구합니다
#agg(['max','min','mean','sum'])
titanic_df.groupby("Pclass")["Age"].agg(['max','min','mean','sum'])

✏️ 결손데이터 처리

  • 결손데이터는 칼럼에 값이 없는, 즉 NULL 인 경우를 의미, 넘파이의 NaN으로 표시
  • 머신러닝하기전에 결손데이터는 대체를 하던지 사용을 포기하던지 처리해줘야 함
     
  • isna() 로 NaN 여부 확인, isnull()
# 9-1 isna()사용
titanic_df.info()
titanic_df.isna() # 모든 값에 대해서 NA인지 아닌지 bool값으로 출력해줌 
titanic_df.isnull() # 이것도 가능
titanic_df.isnull().sum() # 값을 더해서 볼수도 있음 
  • 결손데이터 대체하기 fillna("채워줄 값")
titanic_df["Embarked"].value_counts()
# 갯수 세어보니까 s가 가장 많으니까 이값일 확률이 크다고 판단-> 이걸로 fill 해주기
titanic_df['Embarked'] = titanic_df['Embarked'].fillna("S")
titanic_df['Embarked'].fillna("S",inplace=True)
# NA를 S로 채워주고 원본 업데이트 
titanic_df['Embarked'].isna().sum()
# 다시 NA값 세보면 없음 
  • NaN이 있는 행 제거하기 dropna()
titanic_df.dropna(subset="Age", inplace = True)

✏️ apply lambda 식으로 데이터 가공

  • df.apply(lambda x : x) 이용
titanic_df["Name"].apply(lambda x:len(x))
#lambda사용해서 이름 길이 구하기 
titanic_df["Name_len"] = titanic_df["Name"].apply(lambda x:len(x))
#lambda사용해서 이름 길이 구하여 새로운 컬럼에 넣기 
# 나이에 따라 세분화된 분류를 수행하는 함수 생성
def get_category(age):
    cat = ''
    if age <= 5 : cat = 'Baby'
    elif age <= 12 : cat = 'Child'
    elif age <= 18 : cat = 'Teenager'
    elif age <= 25 : cat = 'Student'
    else : cat = 'Adult'
# get_category값이 적용된  'Age_cat'컬럼을 생성.
titanic_df["Age_cat"] = titanic_df["Age"].apply(lambda x : get_category(x))

✏️ pivot_table

  • excel의 피벗테이블과 비슷한 기능
  • 행인덱스, 열인덱스, 데이터값, 데이터집계함수
  • 데이터프레임.pivot_table(index=행인덱스,columns= 열인덱스, values= 데이터값,aggfunc=집계함수)
# 행: pclass, 열 : sex , age 평균값
pt1 = pd.pivot_table(titanic_df,
               index="Pclass",
               columns="Sex",
               values="Age",
               aggfunc="mean")
# 행: pclass, 열 : sex , Survived 비율-> mean
pt2 = pd.pivot_table(titanic_df,
               index="Pclass",
               columns="Sex",
               values="Survived",
               aggfunc=["mean", 'count','sum'])

✏️ 합치기

  • concat
    • pd.concat([데이터프레임1, 데이터프레임2])
    • pd.concat([데이터프레임1, 데이터프레임2],axis=1)
      → 잘 사용하지 않음
# 단순합치기. concat
df_1 = pd.DataFrame({
     '고객번호' : [100,101,102,103,104,105,106],
     '이름' : ['재석','봉선','하하','미주','준하','진주','이경']
     })
df_2 = pd.DataFrame({
    '고객번호' : [111,112,113,114],
    '이름' : ['현주','창식','해인','미정'],
    '금액' : [10000,20000,15000,5000]
    })
  • merge
    • pd.merge(left, right, on=컬럼명,how=)
       
  • 예시 데이터
cust = pd.DataFrame({
     '고객번호' : [1001,1002,1003,1004,1005,1006,1007],
     '이름' : ['재석','봉선','하하','미주','준하','진주','이경']
     })
order = pd.DataFrame({
    '고객번호' : [1001,1001,1005,1006,1008,1001],
    '금액' : [10000,20000,15000,5000,100000,30000]
    })
  • 두개의 데이터에 모두 존재하는 고객번호를 기준으로 merge
df_merge = pd.merge(cust, order, on="고객번호")
# 두 데이터 프레임에 모두 값이 있을때만 리턴 → 교집합 

  • 왼쪽 데이터 프레임의 값이 다 나오게 하고싶을 때
df_merge2 = pd.merge(cust, order, on = "고객번호",how = "left")
# 왼쪽 테이블인cust를 전체 다 나오게 함 

  • 오른쪽 데이터 프레임의 값이 다 나오게 하고싶을 때
df_merge3 = pd.merge(cust, order, on = "고객번호",how = "right")
# 오른쪽 테이블인 order를 전체 다 나오게 함 

profile
:D

0개의 댓글