[데이터 처리] Pandas - DataFrame

Olivu·2024년 1월 11일
0

Data

목록 보기
4/5
post-thumbnail

DataFrame

DataFrame 생성

Dictionary로 DataFrame 생성

pd.DataFrame(dictioanry변수명)

import pandas as pd

# 딕셔너리 정의
my_dict = {'이름': ['사나', '모모', '쯔위', '나연'],
        '등급': ['Gold', 'Bronze', 'Silver', 'Gold'],
        '점수': [56000, 23000, 44000, 52000]}

# dataframe 생성
df = pd.DataFrame(my_dict)

print(df)

Array로 DataFrame 생성

pd.DataFrame(columns = column리스트명, data = array변수명)

# array 정의
import numpy as np
arr = np.array([['사나', 'Gold', 56000],
               ['모모', 'Bronze', 23000],
               ['쯔위', 'Silver', 44000],
               ['나연', 'Gold', 52000]]
               )

# column 리스트 정의
cols = ['name', 'level', 'score']

# dataframe 생성
import pandas as pd
df = pd.DataFrame(columns = cols, data = arr)

print(df)

csv file로 DataFrame 생성

pd.read_csv('파일명')

  • csv file은 comma seperated value의 약자로, text내에 comma로 각 컬럼들을 구분해 놓은 파일이다.
  • pandas의 read_csv 함수를 사용하여 csv file을 읽어온다.
  • 파일을 읽어오기 전에 파일이 있는 경로로 이동하거나 파일명에 절대경로를 모두 작성해준다.
import pandas as pd

# 현재 경로에 있는 real_estate_price.csv 파일을 dataframe으로 정의
df = pd.read_csv('./real_estate_price.csv', encoding = 'cp949')
  • csv파일을 읽어올때, decode error, encoding error 등이 발생하면, encoding type을 바꿔줘야한다.
  • encoding type은 최초에 파일을 저장했던 OS의 encoding type을 따라간다.
  • 최초에 저장했던 OS의 encoding타입과 현재 내가 사용하고있는 OS의 encoding type이 맞지 않을 경우 에러가 발생한다.
  • windows계열은 encoding type을 'cp949'를 사용하고, linux/unix계열은 utf-8을 사용한다.

DataFrame 정보 확인 & 조작

DataFrame 미리보기

  • DataFrame변수명.head() : 상위 5개행 미리보기
  • DataFrame변수명.tail() : 하위 5개행 미리보기
    함수에 정수값을 넣으면, 5개행이 아닌 원하는 행 개수만큼 미리볼 수 있다.

index

index 조회

dataframe변수명.index

index 변경

DataFrame변수명.index = 새로운 index리스트

  • dataframe index 속성을 새로운 list로 변경/치환할 수 있다.
  • 단, dataframe의 row개수와 새로운 list의 길이가 동일해야 한다.

index 초기화

dataframe변수명.reset_index(drop = True, inplace = True)

index 초기화는 기존 index를 버리고, 0부터 순차적으로 증가하는 정수 index가 할당된다.
기존 index를 버릴지, 보존할지 여부는 parameter에 정의할 수 있다.

  • drop = True : 기존의 index를 버린다
  • drop = False : 기존의 index를 보존한다
  • inplace = True : 기존 dataframe에 업데이트 한다
  • inplace = False : display만하고 기존 dataframe에 업데이트 안 한다

대개, 초기화(reset)와 버리기(drop) 등의 method에 inplace 파라미터가 있는 경우가 많다. 이는 update 여부를 결정하는 parameter로 신중하게 다뤄야 한다. 처음에 inplace = False로 설정하고 결과를 확인한 다음에 True값을 사용하는 것을 권장한다.


Column

Column 조회

dataframe변수명.columns

Column명 변경

  • 여러 column명 변경할 경우
    dataframe변수명.columns = 신규 칼럼 리스트
    columns method를 사용해서 column data에 접근한 후, 동일한 길이의 새로운 칼럼명이 담긴 column list를 대입하여 변경하는 방법
# 신규 칼럼 리스트 정의
new_cols = ['시군구', '번지', '본번']

# 칼럼 변경
df.columns = new_cols
  • 하나의 column명 변경할 경우
    dataframe변수명.rename(columns = {"변경전 칼럼명" : "변경후 칼럼명"}, inplace = True)
    rename 함수 적용하여, dictionary 데이터의 형태로 변경하는 방법(inplace가 True이면 바로 적용, False이면 display만 한다는 뜻)
df.rename(columns = {"거래금액(만원)": "거래금액"}, inplace = True)

Shape 확인

dataframe변수명.shape

  • row, column 개수를 확인할 수 있다.
  • tuple에 나오는 정보 기준, 0번 인덱스가 row, 1번 인덱스가 column이다.
    • axis 0 : row, axis 1 : column 개념이 여기서 나온 개념입니다.
df.shape	# output is (70,3)

Value 확인

DataFrame변수명.values
DataFrame의 Value를 조회하면 2차원 Array형태로 데이터를 리턴한다.

데이터 타입

데이터 타입 확인

DataFrame변수명.dtypes
각 칼럼별로 데이터 타입을 확인할 수 있다.

데이터 타입 변경

dataframe변수명[index명] = dataframe변수명[index명].astype(바꾸고 싶은 데이터타입)

  • DataFrmae은 각 칼럼별로 데이터 타입이 있기때문에, 각 칼럼별로 데이터에 접근을 해서 칼럼단위로 데이터타입을 변경해줘야한다.
  • 변경한 결과가 직접 DataFrame에 적용되지 않기때문에, 해당 결과를 다시 칼럼에 접근해서 대입해줘야한다.
# '전용면적' 칼럼의 데이터타입을 int로 변경
df['전용면적'].astype("int")

# 정의
df['전용면적'] = df['전용면적'].astype("int")

Column별 정보 확인

dataframe변수명.info()

  • info method를 사용하면 column단위의 data type과 null값 개수 등을 확인할 수 있다.
  • non-null값이 null값이 아닌 row의 개수를 나타내므로, 전체 row대비 null값이 포함된 row의 개수를 역산해볼 수 있다.

기초 통계 확인

DataFrame변수명.describe()

  • describe method를 사용하면 평균, 표준편차, 4분위값, 개수 등을 확인할 수 있다.
  • 해당 기초 통계는 Data Analysis를 하는데 사용하는 기초 통계량이 된다.
  • 단, 통계값을 조회할때는 데이터타입이 numerical type인 column들만 조회가 가능하다.

Column의 unique 항목

  • DataFrmae변수명[column명].unique()
    column단위로 데이터에 접근해서, 각 컬럼의 중복값을 제외한 unique항목만 리턴한다.
  • DataFrmae변수명[column명].value_counts()
    column단위로 접근해서, 각 컬럼별 unique 항목별로 count를 집계해준다.

그룹별 통계 확인

DataFrame변수명.groupby(by = "grouping칼럼명").통계함수()

  • groupby는 특정 group으로 묶어서 통계항목을 집계한다.
  • 통계함수에는 describe, sum, mean, count, max, min, std, median, quantile 등이 있다.
# '계약년월' 칼럼의 평균
df.groupby("계약년월").mean()

# '계약년월' 칼럼의 중앙값
df.groupby("계약년월").median()

Data Handling

Data 조회

Indexing

  • DataFrame변수명[column명]
  • DataFrame변수명[column명][row명]
  • DataFrame변수명.loc[index명, column명] : loc 방식
  • DataFrame변수명.iloc[row번호, column번호] : iloc 방식

Slicing

  • DataFrame변수명[시작index명:끝index명, 시작column명:끝column명]
  • DataFrame변수명.loc[시작index명:끝index명, 시작column명:끝column명] : loc 방식
  • DataFrame변수명.iloc[시작row번호:끝row번호, 시작Column번호:끝Column번호] : iloc 방식. 콜론(:) 앞/뒤 번호는 생략 가능. 생략 시 처음부터 끝까지 가져온다는 의미.

조건에 따라 추출

DataFrame변수명.loc[조건식, 시작column명:끝Column명]

  • loc method를 사용하여, 조건에 맞는 row만 추출한다.
  • 조건식에는 and(&)와 or(|) 연산자를 넣을 수 있다.
  • 각 조건식을 연산자로 연결해줄 때는 괄호를 사용하여 연결한다.
# '계약년월'의 값이 202003인 row 추출
df.loc[df['계약년월'] == 202003, :]

# '계약년월'의 값이 202003인 row와 '전용면적'의 값이 59이상인 row 추출
df.loc[(df['계약년월'] == 202003) & (df['전용면적'] > 59), :]

Data 생성/수정

DataFrame은 column 단위로 데이터에 접근한거나, loc,iloc 메서드를 사용하여 데이터를 개별로 접근이 가능하다.

신규 컬럼/데이터 생성

dataframe변수[신규column명] = 초기값
초기값을 임의의 static 데이터로 넣어줄 수도 있고, 함수를 이용하여 값을 설정할 수도 있으며, 기존 칼럼의 값을 조작하여 넣을 수도 있다.

# '계약년도' 칼럼을 새로 만들고 2020을 값으로 넣는다
df['계약년도'] = 2020

함수를 이용한 데이터 생성

1) apply 메서드 사용

  • DataFrame변수명[기존column명].apply(함수명)
  • DataFrame에 칼럼명으로 접근해서 데이터를 조회한 후, apply method를 적용하면, 함수를 적용하여 값을 조작할 수 있다.
  • 이 조작한 값을 새로운 칼럼에 신규 데이터로 입력할 수 있다.
  • 이때, 함수를 fully 신규로 작성해도 좋고, 간단하게 lambda 함수를 사용해서 작성할 수 있다.
# '계약년도' 칼럼의 값에 문자열 인덱싱하고 int 변환 후 '계약년도2' 칼럼을 새로 생성
df['계약년도2'] = df['계약년도'].apply(lambda x: int(str(x)[:4]))

2) string 메서드 사용

  • DataFrame변수명.str.stirng메서드()
  • str 메서드를 이용하면 string 데이터 타입에서 사용할 수 있는 함수들을 pandas dataframe의 칼럼에 적용할 수 있다.
# '거래금액(만원)' 칼럼 데이터에 있는 쉼표(,)를 없애고 동일한 칼럼에 저장
df['거래금액(만원)'] = df['거래금액(만원)'].str.replace(",", "")

# '거래금액(만원)' 칼럼 데이터에 있는 쉼표(,)를 없애고 int로 데이터타입 변환 후 동일한 칼럼에 저장
df['거래금액(만원)'] = df['거래금액(만원)'].str.replace(",", "").astype("int")

결측치

  • 머신러닝에서 데이터를 모델링 할때 결측치(missing value)는 학습에서 에러를 발생시킨다.
  • 따라서, 비어있는 값인 결측치는 별도의 처리가 필요하다.

결측치 확인

dataframe변수명.info() : 각 컬럼별 non-null count를 리턴한다
dataframe변수명.isnull().sum(axis = 0) : 각 컬럼별 null값 개수를 리턴한다
sum(dataframe변수명['column명'].isnull()) : 하나의 칼럼의 null값 개수를 리턴한다

결측치 처리

결측치 처리는 결측치의 양에 따라서 drop과 fill로 구분된다.

1) Drop
결측치를 버리는 결정을 할 때는, 데이터 양이 충분한지, 이 데이터를 버려도 모델링에 문제가 없을지 여부를 충분히 검토 후 버린다. 데이터 편향이 생길 위험이 있다.

  • row를 기준으로 버리기
    DataFrame변수명.dropna(subset = 기준 column명, inplace = True)
    결측치가 10% 미만일때 row 단위로 데이터를 버리는게 일반적이다.

  • column을 기준으로 버리기
    DataFrame변수명.drop(columns = "Drop column명", inplace = True)
    결측치가 30% 이상이고 특정 칼럼 내에 결측치가 너무 많을 경우, 해당 칼럼은 데이터로써의 의미가 없다고 판단하여 Column단위로 버린다. 다만, Data에 대한 도메인 지식을 바탕으로, Drop했을때 정말 문제가 없을지 여부를 면밀히 검토후에 Drop하는 것이 필요하다.

<예제>

# 결측치가 존재하는 row를 기준으로 Drop
df.dropna(subset = ['거래금액'], inplace = True)

# 결측치가 존재하는 column을 기준으로 Drop
df.drop(columns = "전용면적", inplace = True)

2) Fill

  • 이전값 채우기 before fill DataFrame변수명.fillna(method = "bfill")
  • 이후값 채우기 forward fill DataFrame변수명.fillna(method = "ffill")
  • Numerical Data fill
    평균값 fill
    DataFrame변수명[df칼럼명].fillna(DataFrame변수명[df칼럼명].mean(), inplace = True)
    중앙값 fill
    DataFrame변수명[df칼럼명].fillna(DataFrame변수명[df칼럼명].median(), inplace = True)
    최댓값 fill
    DataFrame변수명[df칼럼명].fillna(DataFrame변수명[df칼럼명].min(), inplace = True)
    최솟값 fill
    DataFrame변수명[df칼럼명].fillna(DataFrame변수명[df칼럼명].max(), inplace = True)
  • Categorical data fill
    최빈값 fill
    DataFrame변수명[df칼럼명].fillna(DataFrame변수명[df칼럼명].mode()[인덱스번호])
  • Model Imputation : Correlation 직접 계산 or KNN Impute 방식

<예제>

# before fill
kospi_df['close'] = kospi_df['close'].fillna(method = 'bfill')


# forward fill
kospi_df['volume'] = kospi_df['volume'].fillna(method = 'ffill')


# Numerical Data의 평균값 fill
df_copy_3['전용면적'] = df_copy_3['전용면적'].fillna(df3['전용면적'].mean().astype("int"), inplace = True)

# 거래금액에서 null값이 아닌 row만 따로 추출 -> 추출한 row들의 value값들만 뽑아서, int로 데이터타입 변환 -> 중앙값 계산
median_price = np.median(df_copy_3.loc[df_copy_3['거래금액'].notnull(), "거래금액"].values.astype("int") )

# Numerical Data의 중앙값 Fill & Data Type 변경
df_copy_3['거래금액'] = df_copy_3['거래금액'].fillna(median_price).astype("int")


# mode 함수를 사용하여 Categorical Data fill
salary_df['job_title'] =  salary_df['job_title'].fillna(salary_df['job_title'].mode()[0])

Dummy Variable(One-Hot Encoding)

신규DataFrame변수명 = pd.get_dummies(DataFrame변수명, columns = [One-Hot Encoding 하고싶은 칼럼 리스트])

  • 머신러닝에서 모델링을 할 때, categorical(범주형) column에서 컴퓨터는 자연어 데이터를 그대로 인식할 수 없기 때문에, 수치화를 하는 작업을 label encoding이라고 한다.
  • 이때, label encoding을 하면, 컴퓨터는 category로써의 숫자를 인식하는 것이 아닌, 숫자의 크기를 인식하기 시작한다.
  • 따라서, 각 칼럼들을 각 데이터별로 분할하여 생성하여, 해당 칼럼에 데이터가 있으면 1, 없으면 0 으로 binary값으로 변환하여 데이터를 저장해야한다. 이 작업을 One-Hot Encoding 이라고 하며 이때 생기는 변수값들을 dummy variable이라고도 한다.
  • One-Hot Encoding을 하는 대상 칼럼은, object column중 카테고리가 2개 이상을 우선 확인하고, numerical column중 데이터 중복건수가 여러건 발생하는 칼럼들을 대상으로 한다.
  • dummy variables를 생성하면 column 개수가 많아질 수 있다. Column 대부분 0으로 채워지고, 일부만 1로 채워진 벡터를 sparse vector라고 한다. Sparse vector는 "차원의 저주"를 만들어, ML 학습을 방해하는 요소로 작용할 수 있다. 과도한 차원의 증가를 막기 위해 ML에서는 embedding, PCA 등의 차원축소 기법을 사용하거나 유사 그룹들을 묶어주는 feature engineering 작업을 수행하기도 한다.

Data 합치기

  • 데이터를 합치는 함수는 concat과 merge(join)이 있다.
  • Concat은 이어 붙이는 기능
  • Merge는 특정 key를 기준으로 병합시키는 기능이다.

1) Concat

DataFrame변수명 = pd.concat([이어붙일 DataFrame변수명 리스트], axis = 기준 축)

  • axis = 0 : row-wise concat
  • axis = 1 : column-wise concat

<예제>

salary_df.shape					# output is (3755, 11)
salary_df_company_size.shape	# output is (3755, 3)

# salary_df와 salary_df_company_sized의 row 개수가 동일하기 때문에 두개의 dataframe을 옆으로(column축) 합친다
salary_df_new = pd.concat([salary_df, salary_df_company_size], axis = 1)

2) Merge

DataFrame변수명 = pd.merge(dataframe_1, dataframe_2, on = 기준 column명, how = join방식)

  • Join 방식에는 크게 inner join과 outer join이 있다.
  • key가 기준이 되고, 이외의 모든 column은 합친다.
  • inner : 일치하는 값이 있는 경우, 공통으로 가지고 있는 행만 가져온다.
  • left(left outer join) : dataframe_1에 있는 모든 데이터를 가져오고, dataframe_2의 column에서 없는 데이터들은 null 처리
  • right(right outer join) : dataframe_2에 있는 모든 데이터를 가져오고, dataframe_1의 column에서 없는 데이터들은 null 처리
  • outer(full outer join): axis 0 방향으로 concat한 것과 동일하다

<예제> inner join

# 'ID' column을 기준으로 sales_df와 user_df의 공통된 부분만 합친다
new_df = pd.merge(sales_df, user_df, on = 'ID', how = 'inner')

# join 하기 전 각 df 모양 확인
sales_df.shape, user_df.shape		# output is ((101692, 9), (3590, 4))

# join 한 후 df 모양 확인. row의 개수가 101692보다 작아졌다. 6개의 row가 공통 부분이 아니라는 것을 확인할 수 있다. 
new_df.shape						# output is (101686, 12)

<예제> left outer join

new_df_2 = pd.merge(sales_df, user_df, on = 'ID', how = 'left')

# join을 한 df 모양 확인. sales_df의 row 개수와 동일한 것을 확인할 수 있다. 
new_df_2.shape				# output is (101692, 12)

<예제> full outer join

new_df_3 = pd.merge(sales_df, user_df, on = 'ID', how = 'outer')

# join한 후 모양 확인. row의 개수가 sales_df보다 늘어난 것을 확인할 수 있다. 왜???
new_df_3.shape		# output is (101741, 12)

Variable Screening

  • 변수들이 무의미하게 나열되고 있는 것은, ML modeling에서 차원의 저주를 발생시킨다.
  • Small data, large column은 차원의 저주를 만들기 때문에 데이터 사이즈를 늘리거나, column의 개수를 줄여줄 필요가 있다.
  • Variable을 screening할때는 feature selection과 feature extraction 방법이 있다.

Feature Selection

  • 중복되고 의미없는 변수(correlation이 높거나 collinearity가 높은 변수)를 제거하는 방식으로 변수를 줄여나가는 방식
  • classical statistic에 기반한 방식 :
    1) mRMR : 타겟 변수(Y)와 관련성이 높고 서로간의 중복된 정보를 최소화하여 가진 변수들의 집단을 추출하는 변수 선택 알고리즘
  • Model에 기반한 방식 :
    1) Boruta : 다중공선성은 고려하지 않고 과적합만을 고려하기 위한 방법이다. 즉, 출력변수를 예측하는데 필요한 모든 입력변수를 선택하는 방법이다.
    2) All but X : ML 모델을 돌려서 한번 반복할때마다 하나의 입력변수를 제거하며, 학습된 모델의 성능 손실을 통해 입력변수에 미치는 영향을 파악한다.

Feature Extraction

기존 입력변수들의 조합으로 새로운 특징을 생성하는 방식. Auto Encoder, PCA 등

profile
천천히 꾸준히 기록

0개의 댓글

관련 채용 정보