반응형

안녕하세요!

오늘은 Pandas의 apply 메서드를 사용하는 방법을 알아보도록 하겠습니다.

 

종종 pandas로 csv 파일을 열어 dataframe을 만들 때, 

각 행을 계산한다던가, 열을 계산하여야 할 때가 있습니다.

이때 pandas 의 apply 메서드를 사용하면 만들어 둔 함수를 간편하게 적용하여 계산이 가능합니다.

 

데이터 준비

데이터는 kaggle의 Lemonade-Orange-stand를 사용해 보겠습니다.

https://www.kaggle.com/datasets/adisak/lemonade-stand

 

Lemonade-Orange-stand

Lamonade and Orange Stand sales

www.kaggle.com

이 데이터는 각 날짜의 레몬, 오렌지 에이드 판매량을 보여주는 데이터셋입니다.

링크를 들어가서 Lemonade2016-2.csv 파일을 다운받아 줍니다.

그 후 csv파일을 아래와 같이 열어 줍니다.

import pandas as pd
df = pd.read_csv('Lemonade2016-2.csv')
df


각 컬럼의 의미는 다음과 같습니다.

Date: 날짜

Location: 판매장소(공원/해변가)

Lemon: 레몬에이드 판매량(잔)

Orange: 오렌지에이드 판매량(잔)

Temperature: 기온(화씨/ºF)

Leaflets: 배포한 전단지 수

Price: 가격($)

 

Series에서 apply 적용하기 - 1개의 인자를 전달받는 함수
현재 df에 있는 temperature은 화씨온도로 한국에서 쓰는 섭씨온도랑 단위가 다릅니다.
때문에 온도를 이해하기 쉽게 섭씨 온도로 바꿔주는 작업을 해보도록 하겠습니다.
 
화씨온도에서 섭씨온도로 변환하는 식은 아래와 같습니다.

°C = (°F−32)×5/9

이것을 'to_C'라는 함수로 만들어 보겠습니다.
#화씨->섭씨 함수
# (temperature - 32) * 5 / 9
def to_C(x):
    C = (x - 32) * 5 / 9
    # 소수 셋째자리에서 반올림
    C = round(C,2)
    return C

그리고 df에서 따로 날짜컬럼만 빼어서 apply 함수 적용 후 새로운 df열에 할당해 주도록 하겠습니다.

# 기온(temperature)을 섭씨(ºC)로 변환
temp = df['Temperature']
# apply 함수 적용 후 새로운 열에 섭씨온도 추가해 주기
df['temp_C'] = temp.apply(to_C)
df
 
오른쪽 맨 끝열에 섭씨 온도가 잘 추가되었습니다.
 
2개의 인자를 전달받는 함수 - 25센트짜리 레몬에이드 판매액을 구하기
이번에는 각 날짜의 레몬에이드 판매액이 얼마인지 apply를 사용해 구해보도록 하겠습니다.
레몬에이드 판매액은
 
레몬에이드 판매 수 x 가격
 
으로 구할 수 있습니다.
이번에는 레몬에이드가 25센트일때의 그날의 판매액을 구하는 것이므로
먼저 레몬에이드가 25센트인 날만 필터링하여줍니다.
# price가 0.25인것만 필터링
cent_25 = df[df['Price'] == 0.25]
cent_25

 이렇게 25센트인 날만 추출이 완료되었습니다.

 

 
그 후, 판매액을 구하는 함수를 만들어 apply로 적용해 줍니다.
 
apply 적용 시 Lemon열에서 적용하여 줍니다. price는 0.25로 모든 열이 같으므로
price 인자를 전달할 때 price=0.25로 고정하여 줍니다.
#판매액 을 구하는 함수
def lemon_money(x, price):
    total = x * price
    return total
cent_25['Lemon'].apply(lemon_money,price=0.25)
이렇게 판매액 계산이 완료되었습니다.
 
Dataframe에서 apply 적용하기 - 3개의 인자를 입력받아 계산하는 경우
이번에는 레몬 에이드와 오렌지 에이드 판매량을 합쳐 각 날짜의 총 판매액을 구해보도록 하겠습니다.
이것을 함수로 작성한다면 일반적인 경우는 아래와 같이 작성할 것 입니다.
 
(레몬에이드 판매량 +오렌지에이드 판매량) *가격
def total(x,y,price):
    total_money = (x+y)*price
    return total_money
하지만 dataframe에 apply를 적용할 때는 행 단위 또는 열 단위로만 값을 입력받기 때문에,
위의 함수식을 한개의 인자를 받는 함수로 바꾸어야 합니다.
그 후 이 함수식 안에서 3개의 인자를 생성하는 방향으로 함수를 수정하겠습니다.
 
이 때, df에서 사용하는 값이 각 행의 'Lemon', 'Orange', 'Price' 컬럼 이므로 
이를 각각 함수 내에서 x,y,price라는 변수 생성후 열 번호로 할당을 해주도록 하겠습니다.
 
각 컬럼의 위치와 인덱스를 아래와 같이 확인하여 줍니다.
#컬럼확인
df.columns​

#컬럼 번호 확인
for itr,i in enumerate(df.columns):
    print(itr,' : ',i)
그 후 함수를 한 개의 인자값을 받는 함수로 수정하여 줍니다.
# 1개의 인자값을 가지는 함수로 변경
# x=레몬에이드,y=오렌지에이드,price=가격 각각 열 위치로 변수 할당
def total(col):
    x = col[2] #Lemon
    y = col[3] #Orange
    price = col[6] #Price
    total_money = (x+y)*price
    return total_money
마지막으로, apply를 사용하여 해당 함수를 적용하여 줍니다.
각 열을 인자값으로 사용하므로 axis=1로 설정해 줍니다.(axis=0은 행방향)
#df에 적용하여 리턴값 새 열에 할당
# 열 기준이므로 axis = 1
df['total'] = df.apply(total,axis=1)
df​
이렇게 total 열에 총 판매액 계산이 잘 되었습니다.

 

전체 코드
import pandas as pd

df = pd.read_csv('Lemonade2016-2.csv')

# 기온(temperature)을 섭씨(ºC)로 변환
temp = df['Temperature']

#화씨->섭씨 함수
# (temperature - 32) * 5 / 9
def to_C(x):
    C = (x - 32) * 5 / 9
    # 소수 셋째자리에서 반올림
    C = round(C,2)
    return C
    
# apply 함수 적용 후 새로운 열에 섭씨온도 추가해 주기
df['temp_C'] = temp.apply(to_C)

# price가 0.25인것만 필터링
cent_25 = df[df['Price'] == 0.25]

#판매액 을 구하는 함수
def lemon_money(x, price):
    total = x * price
    return total
cent_25['Lemon'].apply(lemon_money,price=0.25)

#컬럼확인
df.columns
#컬럼 번호 확인
for itr,i in enumerate(df.columns):
    print(itr,' : ',i)

# 1개의 인자값을 가지는 함수로 변경
# x=레몬에이드,y=오렌지에이드,price=가격 각각 열 위치로 변수 할당
def total(col):
    x = col[2] #Lemon
    y = col[3] #Orange
    price = col[6] #Price
    total_money = (x+y)*price
    return total_money
    
#df에 적용하여 리턴값 새 열에 할당
# 열 기준이므로 axis = 1
df['total'] = df.apply(total,axis=1)
df
코드파일

apply_practice.ipynb
0.06MB

 

참고자료

Do it! 데이터 분석을 위한 판다스 입문

 

마무리

apply는 활용도가 높은 메서드 입니다. 유용히 사용하셨으면 좋겠습니다 ㅎㅎ

 

+ Blogspot 블로그도 개설하였습니다!

종종 방문해 주시면 좋겠습니다 ㅎㅎ

https://wonhwa1.blogspot.com/2022/10/python-pandas-apply.html

 

[python] pandas Apply를 사용하여 함수를 한번에 적용하기

Apply 종종 pandas로 csv 파일을 열어 dataframe을 만들 때,  각 행을 계산한다던가, 열을 계산하여야 할 때가 있습니다. 이때 pandas 의 apply 메서드를 사용하면 만들어 둔 함수를 간편하게 적용하여 계산

wonhwa1.blogspot.com

 

반응형
반응형

Pandas는 데이터 분석을 할 때 필수적으로 사용하는 파이썬 라이브러리입니다.

오늘은 유용하게 쓰일 수 있는 판다스의 메소드 몇 가지를 간단히 알아보도록 하겠습니다.

Groupby 그룹바이

pandas.groupby() 메서드는 그룹 연산을 도와주는 메서드입니다.

데이터를 집계하면 전체 데이터를 더 분석하기 쉽고 한눈에 파악하는데 용이하기 때문에 groupby는 정말 유용합니다.

그룹바이를 이용하면 평균, 합, 표준편차 등등 여러 값을 구할 수 있습니다.

오늘은 저번에 bar_chart_race에서 사용한 코로나 확진자 데이터를 이용하여 집계해 보도록 하겠습니다.

데이터셋

corona_kr.csv
1.61MB

위의 데이터를 다운받아 주세요:)

그 후 파일을 열어 어떤 데이터를 가지고 있는지 확인해 보도록 하겠습니다.

####### Pandas Groupby #######

import pandas as pd

#데이터셋 준비
df = pd.read_csv('corona_kr.csv')
print(df.head())

출력:

이렇게 업데이트된 날짜, 사망인원, 확진자, 지역명(한국어) 등등 여러 정보가 나와 있습니다.

이 데이터는 2020년부터~2021년 11월 초반까지의 데이터입니다.

지역별 총 코로나 확진자 수를 groupby sum을 이용해 구해 보도록 하겠습니다.

사용방법은 아래와 같습니다.

df.groupby('합계를 구할 기준컬럼 이름').합계할 값 컬럼이름.하고싶은 그룹연산()

 

##### groupby sum #####
## 지역별 총 코로나 확진자 수 구하기##

corona_by_region= df.groupby('gubun').defCnt.sum()
print(corona_by_region)

출력:

이렇게 지역별 합이 만들어졌습니다.

이번에는 기간 내 코로나 확진자 지역 평균을 mean()을 사용하여 구해보도록 하겠습니다.

##### groupby mean #####
##지역별 평균 확진자 수  ##

means_by_region = df.groupby('gubun').defCnt.mean()

print(means_by_region)

출력:

이렇게 하루 평균 지역 확진자 발생 인원을 구했습니다.

마지막으로는 describe를 알아보도록 하겠습니다.

describe는 전체적인 집계 정보를 보여줍니다.

위에서 구한 합계, 평균뿐만 아니라 표준편차, 최솟값, 최댓값, 4 분위 값 등등을 확인할 수 있습니다.

##### groupby describe #####
#코로나 확진자에 대한 전체적인 정보 반환#
print(df.groupby('gubun').defCnt.describe())

출력:

이렇게 데이터에 대한 전체적인 정보를 describe를 사용하여 확인 할 수 있습니다 :)

 

pivot_table 피벗 테이블

pivot_table 메서드는 데이터 프레임의 행과 열의 위치를 내가 원하는 대로 배치할 수 있도록 도와줍니다.

코로나 데이터에서는 지역 컬럼이 따로 있고 하루마다 확진자 수가 갱신이 됩니다.

지역별 확진자 수를 한눈에 보기 위해 (1)열 수를 정리해주고,

피벗 테이블을 사용하여 (2)지역열에 있는 행값들을 열로 위치하고, 

각 지역 (3)열 값의 값으로는 확진자 수(defCnt)를 넣어 주도록 하겠습니다.

#### pandas pivot table ####
#필요한 정보만 df2에 담기
df2 = df.iloc[:,1:5]
print(df2)

출력:

corona_pivotTable = df2.pivot_table(
                    index=['createDt','deathCnt'],
                    columns='gubun',
                    values='defCnt' )
print(corona_pivotTable)

출력:

[원본 데이터]

[피벗 후 데이터]

위와 같이 아까는 행에 있던 지역 명들이 열값으로 옮겨졌음을 확인할 수 있습니다.

pivot_table 메서드에서 3개의 인자를 사용하여 데이터프레임을 피봇 해주었는데요,

index =  그대로 유지할 열 이름 입력

columns = 피벗할 열 이름 입력

values = 피벗할 열의 값이 될 열 이름 입력

위와 같이 사용하여 입력하면 됩니다:)

melt

마지막으로 알아볼 메서드는 melt인데요,

melt는 긴 열값을 가지고 있는 데이터를 정리할 때 유용합니다.

예를 들어 서울시 상권분석서비스 소득소비 데이터를 확인해보면,

(아래의 링크에서 데이터를 다운받아 주세요.)

http://data.seoul.go.kr/dataList/OA-15571/S/1/datasetView.do

 

열린데이터광장 메인

데이터분류,데이터검색,데이터활용

data.seoul.go.kr

##데이터 셋 불러오기##
seoul=pd.read_csv('서울시_우리마을가게 상권분석서비스(상권배후지-소득소비).csv',encoding='cp949')
print(seoul)

출력:

위와 같이 의류지출총금액, 생활용품지출총금액, 의료지출금액 등등 열이 길게 늘어져 있는것을 확인할 수 있습니다.

이 데이터를 melt를 사용해서 지출 종류별로 열을 행으로 만들어 주어 데이터를 만들어 보도록 하겠습니다.

행으로 합쳐질 새로운 열의 이름을 '지출 종류'라 이름짓고, 원래 데이터에 있던 지출금액을 '금액'으로 열이름을 지정하겠습니다.

#### pandas melt ####
seoul_melt = pd.melt(seoul,id_vars=['기준 년 코드','기준_분기_코드','상권_구분_코드','상권_구분_코드_명',
                                    '상권_코드','상권_코드_명','월_평균_소득_금액'
                                    , '소득_구간_코드','지출_총금액']
                    , var_name='지출종류',value_name='금액')
# 변경된 부분 한눈에 확인할 수 있도록 앞에 부분 자르기
a = seoul_melt.iloc[:,8:]
print(a)

출력:

위와 같이 아까는 열이었던 식료품, 유흥, 의료 지출 총 금액이 하나의 열의 행값으로 합쳐지고 그 값도 옆에 '금액' 열로 정리되었음을 확인할 수 있습니다.

melt 메서드 인자는 아래와 같이 사용할 수 있습니다.

id_vars = 그대로 유지할 열 이름, 2개이상 입력 시 []로 묶어 입력하기

value_vars = 행으로 바꿀 열 이름

var_name = value_vars로 바꿀 열의 새로운 이름 만들기

value_name =  var_name으로 바꾼 열의 원래 데이터값의 새로운 열 이름

 

전체 코드
####### Pandas Groupby #######

import pandas as pd

#데이터셋 준비
df = pd.read_csv('corona_kr.csv')
print(df.head())


##### groupby sum #####
## 지역별 총 코로나 확진자 수 구하기##

corona_by_region= df.groupby('gubun').defCnt.sum()
print(corona_by_region)

##### groupby mean #####
##지역별 평균 확진자 수  ##

means_by_region = df.groupby('gubun').defCnt.mean()

print(means_by_region)

##### groupby describe #####
#코로나 확진자에 대한 전체적인 정보 반환#
print(df.groupby('gubun').defCnt.describe())


#### pandas pivot table ####
df2 = df.iloc[:,1:5]
print(df2)
corona_pivotTable = df2.pivot_table(
                    index=['createDt','deathCnt'],
                    columns='gubun',
                    values='defCnt' )
print(corona_pivotTable)



#### pandas melt ####


##데이터 셋 불러오기##
seoul=pd.read_csv('서울시_우리마을가게 상권분석서비스(상권배후지-소득소비).csv',encoding='cp949')
print(seoul)

seoul_melt = pd.melt(seoul,id_vars=['기준 년 코드','기준_분기_코드','상권_구분_코드','상권_구분_코드_명',
                                    '상권_코드','상권_코드_명','월_평균_소득_금액'
                                    , '소득_구간_코드','지출_총금액']
                    , var_name='지출종류',value_name='금액')
a = seoul_melt.iloc[:,8:]
print(a)

 

코드 파일

groupby_pivot.py
0.00MB

참고 자료

책 「데이터 분석을 위한 판다스 입문」 - 이지스퍼블리싱

마무리

오늘은 데이터 전처리 시 유용하게 사용가능한 메서드 3개를 알아보았습니다ㅎㅎ

알고싶은 다른 pandas 기능이 있으시다면 댓글로 남겨주세요 (o'◡'o)

반응형
반응형

안녕하세요~! 오늘은 공공데이터 openAPI의 xml을 Pandas DataFrame으로 변환하여 보도록 하겠습니다.
json에서 DataFrame으로의 변환은 여기를 클릭해서 확인해 주세요 :)

step1. 데이터 활용신청하기

공공데이터 포털

 

공공데이터 포털

국가에서 보유하고 있는 다양한 데이터를『공공데이터의 제공 및 이용 활성화에 관한 법률(제11956호)』에 따라 개방하여 국민들이 보다 쉽고 용이하게 공유•활용할 수 있도록 공공데이터(Datase

www.data.go.kr

위 사이트에 접속 후 로그인하여 주세요.
여기서 '코로나'를 검색해 주세요.
그 후 스크롤 다운을 하셔서 아래의 내용을 찾으신 후 API 활용신청을 해 주세요.

https://www.data.go.kr/data/15043378/openapi.do

 

공공데이터활용지원센터_보건복지부 코로나19 시·도발생 현황

코로나19감염증으로 인한 시.도별 신규확진자,신규사망자,격리중인환자수,격리해제환자수등에 대한 현황자료 (이 제공자료는 관련 발생 상황에 대한 정보를 신속 투명하게 공개하기 위한 것으

www.data.go.kr

또는 위의 링크를 클릭하셔도 됩니다 :)
활용신청을 했다면 마이페이지에 들어가 주세요 :)

오픈 API > 개발계정> 공공데이터 활용지원센터_보건복지부 코로나19 시.도 발생 현황을 클릭해 주세요.

그 후 상세설명 클릭하여 요청 값 및 출력 값(컬럼)을 확인해 주세요.
각각의 컬럼 값에 어떤 내용이 있는지 확인하기 위해서 꼭 필요하기 때문에 잘 읽어주세요.

스크롤 다운을 하면 아래의 샘플코드> Python을 클릭하여 코드를 참고하여 xml을 불러오면 됩니다.

 

step2. API를 사용하여 xml 불러오기

이제부터 데이터를 요청하는 코드를 작성해 보도록 하겠습니다.

# 모듈 import
import requests
import pprint

#인증키 입력
encoding = '발급받은 인코딩 인증키를 복사하여 붙여넣기 해 주세요.'
decoding = '발급받은 디코딩 인증키를 복사하여 붙여넣기 해 주세요.'

#url 입력
url = 'http://openapi.data.go.kr/openapi/service/rest/Covid19/getCovid19SidoInfStateJson'
params ={'serviceKey' : decoding , 
'pageNo' : '1', 
'numOfRows' : '10', 
'startCreateDt' : '2020', 
'endCreateDt' : '20211103' }

response = requests.get(url, params=params)

# xml 내용
content = response.text

# 깔끔한 출력 위한 코드
pp = pprint.PrettyPrinter(indent=4)
#print(pp.pprint(content))

위의 내용까지는 전 게시글의 내용과 비슷합니다.
서비스키에 들어갈 수 있는 인증키로는 인코딩과 디코딩이 있는데 인코딩으로 실행하였을 때 오류가 나서 디코딩 인증키를 넣어 요청하였습니다.

step3. xml을 DataFrame으로 변환하기

xml 문서는 <item>안에 각 값이 태그 형식<>으로 들어 있습니다.
이 점을 이용해 뷰티플수프를 이용하여 파싱해보도록 하겠습니다.

### xml을 DataFrame으로 변환하기 ###
from os import name
import xml.etree.ElementTree as et
import pandas as pd
import bs4
from lxml import html
from urllib.parse import urlencode, quote_plus, unquote

## 각 컬럼 값 ## (포털 문서에서 꼭 확인하세요)
"""
SEQ : 게시글번호(국내 시도별 발생현황 고유값)
CREATE_DT: 	등록일시분초
DEATH_CNT: 	사망자 수
GUBUN: 	시도명(한글)
GUBUN_CN: 	시도명(중국어)
gubunEn: 시도명(영어)
INC_DEC: 전일대비 증감 수
ISOL_CLEAR_CNT: 격리 해제 수
QUR_RATE: 10만명당 발생률
STD_DAY: 기준일시
UPDATE_DT: 수정일시분초
DEF_CNT: 확진자 수
ISOL_ING_CNT: 격리중 환자수
OVER_FLOW_CNT: 해외유입 수
LOCAL_OCC_CNT: 지역발생 수

""" 

#bs4 사용하여 item 태그 분리

xml_obj = bs4.BeautifulSoup(content,'lxml-xml')
rows = xml_obj.findAll('item')
print(rows)

출력:

위의 내용만으로 한 눈에 어떤 정보가 있는지 보기 힘들기 때문에 데이터 프레임으로 만들기 전 이에 필요한
각각의 행값, 열 이름값, 데이터값을 추출하는 코드를 작성해 보겠습니다.

# 각 행의 컬럼, 이름, 값을 가지는 리스트 만들기
row_list = [] # 행값
name_list = [] # 열이름값
value_list = [] #데이터값

# xml 안의 데이터 수집
for i in range(0, len(rows)):
    columns = rows[i].find_all()
    #첫째 행 데이터 수집
    for j in range(0,len(columns)):
        if i ==0:
            # 컬럼 이름 값 저장
            name_list.append(columns[j].name)
        # 컬럼의 각 데이터 값 저장
        value_list.append(columns[j].text)
    # 각 행의 value값 전체 저장
    row_list.append(value_list)
    # 데이터 리스트 값 초기화
    value_list=[]

여기서 name_list는 열 이름들을 가지고 있고, row_list는 한 행의 값을 가지고 있습니다.
이제 위 변수들에 저장된 내용을 가지고 DataFrame으로 만들어 보겠습니다.

#xml값 DataFrame으로 만들기
corona_df = pd.DataFrame(row_list, columns=name_list)
print(corona_df.head(19))

가끔 데이터 프레임을 만들 때  Assertion Error가 나는 경우가 있는데 이때는 columns를 사용하지 마시고 df를 만들면 됩니다.

#xml값 DataFrame으로 만들기
#Assertion Error가 난 경우
corona_df = pd.DataFrame(row_list)
# 이후에 컬럼을 설정해 주세요.

출력:

깔끔하게 데이터프레임으로 만들어짐을 확인할 수 있습니다 :)
추가로 만들어진DataFrame을 csv파일로 저장하고 싶다면 아래의 코드를 추가하시면 됩니다.

#DataFrame CSV 파일로 저장
corona_df.to_csv('corona_kr.csv', encoding='utf-8-sig')

 

전체 코드
# 모듈 import
import requests
import pprint


#인증키 입력
encoding = '발급받은 인코딩 인증키를 복사하여 붙여넣기 해 주세요.'
decoding = '발급받은 디코딩 인증키를 복사하여 붙여넣기 해 주세요.'

#url 입력
url = 'http://openapi.data.go.kr/openapi/service/rest/Covid19/getCovid19SidoInfStateJson'
params ={'serviceKey' : decoding , 'pageNo' : '1', 'numOfRows' : '10', 'startCreateDt' : '2020', 'endCreateDt' : '20211103' }

response = requests.get(url, params=params)

# xml 내용
content = response.text

# 깔끔한 출력 위한 코드
pp = pprint.PrettyPrinter(indent=4)
#print(pp.pprint(content))

### xml을 DataFrame으로 변환하기 ###
from os import name
import xml.etree.ElementTree as et
import pandas as pd
import bs4
from lxml import html
from urllib.parse import urlencode, quote_plus, unquote

## 각 컬럼 값 ## (포털 문서에서 꼭 확인하세요)
"""
SEQ : 게시글번호(국내 시도별 발생현황 고유값)
CREATE_DT: 	등록일시분초
DEATH_CNT: 	사망자 수
GUBUN: 	시도명(한글)
GUBUN_CN: 	시도명(중국어)
gubunEn: 시도명(영어)
INC_DEC: 전일대비 증감 수
ISOL_CLEAR_CNT: 격리 해제 수
QUR_RATE: 10만명당 발생률
STD_DAY: 기준일시
UPDATE_DT: 수정일시분초
DEF_CNT: 확진자 수
ISOL_ING_CNT: 격리중 환자수
OVER_FLOW_CNT: 해외유입 수
LOCAL_OCC_CNT: 지역발생 수

""" 

#bs4 사용하여 item 태그 분리

xml_obj = bs4.BeautifulSoup(content,'lxml-xml')
rows = xml_obj.findAll('item')
print(rows)
"""
# 컬럼 값 조회용
columns = rows[0].find_all()
print(columns)
"""

# 각 행의 컬럼, 이름, 값을 가지는 리스트 만들기
row_list = [] # 행값
name_list = [] # 열이름값
value_list = [] #데이터값

# xml 안의 데이터 수집
for i in range(0, len(rows)):
    columns = rows[i].find_all()
    #첫째 행 데이터 수집
    for j in range(0,len(columns)):
        if i ==0:
            # 컬럼 이름 값 저장
            name_list.append(columns[j].name)
        # 컬럼의 각 데이터 값 저장
        value_list.append(columns[j].text)
    # 각 행의 value값 전체 저장
    row_list.append(value_list)
    # 데이터 리스트 값 초기화
    value_list=[]

#xml값 DataFrame으로 만들기
corona_df = pd.DataFrame(row_list, columns=name_list)
###assertion error의 경우###
###corona_df = pd.DataFrame(row_list)
print(corona_df.head(19)) 

#DataFrame CSV 파일로 저장
corona_df.to_csv('corona_kr.csv', encoding='utf-8-sig')

 

코드 파일

corona_DataFrame.py
0.00MB

참고 사이트

Python (파이썬) 공공데이터 수집 (Open API - XML)

 

Python (파이썬) 공공데이터 수집 (Open API - XML)

공공데이터포털의 특징은 자료를 활용을 요약하자면 1. 회원 가입 후 '사용자 인증키'를 생성해야한다. 2. 이후 원하는 데이터를 '활용 신청'을 해서 승인이 떨어지고 활용 권한을 획득해야한다

greendreamtrre.tistory.com

 

마무리

저번에는 json -> DataFrame 하는 방법을 공유하였고
이번에는 xml -> DataFrame 하는 방법을 공유하였습니다.
다음 시간에는 위에서 만든 corona_df를 가지고 bar_chart_race로 시각하여 보도록 하겠습니다 ^ㅇ^
이해 가지 않는 내용이나 질문이 있으면 댓글로 남겨 주세요 :)

반응형
반응형

데이터 분석을 하다 보면 pandas를 필수적으로 쓰게 되는데

원본 데이터 값 자체가 양이 많기도 하고 데이터 타입 자체도 통일 성 없이 한 열 값 안에 

int, float, str 타입이 섞여 있기도 한다.

예시데이터

위의 경우 인허가일자와 휴업 일자가 문자열도 섞여있고 중간에 NaN값, 스트링 안에 필요 없는 부호, 빈 값까지..

총체적 난국임을 알 수 있다.  위의 데이터를 pandas를 사용해서 깔끔하게

전부 int(정수)로 변환하여 보겠다.

#예시 데이터 프레임
import pandas as pd
from numpy import NaN, NAN, nan #누락값 넣기 위한 모듈 불러오기

df = pd.DataFrame({'구분':[1,2,3,4,5,6], 
                   '인허가일자':[2016312,'2020.02.01',201603,99991230,1980,192012],
                   '휴업일자':[20160312.0,'2020 320',201603.0,NaN,'2020-02-22','']})
#df = df.set_index('구분')
df

출력:

step1. 빈칸을 NaN으로 채워주기

# 비어 있는 값을 NaN으로 바꾸기
df = df.replace(r'^\s*$',NaN, regex=True)
df

출력:

이렇게 빈 칸을 NaN으로 채워준다.

step 2. NaN을 다른 값으로 변경해주기

#누락값 처리 NaN을 다른 값으로 변경하기
df = df.fillna(0) #다른 값 변경시 .fillna(변경할 숫자).iloc[행위치, 열위치] 입력하여 변경
df

출력:

그러면 NaN값이 0으로 채워짐을 확인할 수 있다.

step3. 문자열을 정수로 변환하기

이제 문자열을 정수로 변환하여야 하는데

우선 스트링 값을 가지는 곳에 특수문자와 공백을 제거 후 

pandas apply를 이용하여 데이터 프레임에 함수를 한 번에 적용해주도록 하겠다.

#문자열을 정수로 변경하기
import re
#string의 특수문자 제거하는 함수
def cleanString(x):
    x1 = ''
    if type(x1) == type(x):
        x = re.sub('[-=.#/?:$}]', '', x) #특수문자 제거
        x1 = x.replace(" ","") #공백제거
        return int(x1)
    else:
        return x

# 인허가일자 str int로 변환하기
df['인허가일자']=df['인허가일자'].apply(cleanString)
# 휴업일자 str int로 변환하기
df['휴업일자']=df['휴업일자'].apply(cleanString)
#휴업일자 float타입을 int로 바꿔주기
df['휴업일자'] =df['휴업일자'].astype('int64')

df

출력:

그럼 이렇게 깔끔하게 모두 정수로 변환이 되었음을 확인할 수 있다. :)

반응형

+ Recent posts