Merge_Concat
두 데이터 프레임 연결하기
import pandas as pd
df1 = pd.DataFrame({
'id': [1, 2, 3],
'customer_id': [1, 2, 3],
'customer_name': ['Robert', 'Peter', 'Dave']
}, columns=['id', 'customer_id', 'customer_name'])
df1

df2 = pd.DataFrame({
'id': [1, 2, 4],
'order_id': [100, 200, 300],
'order_date': ['2021-01-21', '2021-02-03', '2020-10-01']
}, columns=['id', 'order_id', 'order_date'])
df2

concat()
- 두 데이터프레임을 연결해서 하나의 데이터프레임으로 만들 수 있음
- 두 데이터프레임을 위/아래 또는 왼쪽/오른쪽으로 연결하기만 함
- pd.concat([데이터프레임1, 데이터프레임2])
pd.concat([df1, df2])

axis: 0 이면(디폴트) 위에서 아래로 합치고, 1 이면 왼쪽과 오른쪽으로 합침
doc = pd.concat([df1, df2], axis=1)
doc.head()

두 데이터 프레임 합치기
merge()
- merge(데이터프레임1, 데이터프레임2) : 두 데이터프레임에 동일한 이름을 가진 컬럼을 기준으로 두 데이터프레임을 합침
pd.merge(df1, df2)

- merge(데이터프레임1, 데이터프레임2, on=기준컬럼명) : 기준 컬럼을 명시할 수도 있음
pd.merge(df1, df2, on='id')

merge() 를 통해 어떻게 두 데이터프레임을 결함시킬 것인가에 대해 보다 상세한 기능을 제공함
- merge(데이터프레임1, 데이터프레임2, how=결합방법)
- 결합방법
- inner : 내부 조인 - SQL의 INNER JOIN 과 동일
- outer : 완전 외부 조인 - SQL의 OUTER JOIN 과 동일
- left : 왼쪽 우선 외부 조인 - SQL의 LEFT OUTER JOIN 과 동일
- right : 오른쪽 우선 외부 조인 - SQL의 RIGHT OUTER JOIN 과 동일
merge() 함수는 SQL의 JOIN 기능과 동일함
- SQL JOIN: 두 개 이상의 테이블로부터 필요한 데이터를 연결해 하나의 포괄적인 구조로 결합시키는 연산
1. inner : 내부 조인 - SQL의 INNER JOIN 과 동일 (디폴트)
- 동작 방식
- on의 컬럼값이 두 데이터프레임에서 동일한 행 찾기
- 각 동일한 행의 컬럼/컬럼값만 가져오기

2. outer : 완전 외부 조인 - SQL의 OUTER JOIN 과 동일
- 동작 방식
- on의 컬럼값이 두 데이터프레임에서 동일한 행 찾기
- 각 동일한 행의 컬럼/컬럼값 가져와 붙이기
- 각 데이터프레임에서 on의 컬럼값이 다른 나머지 행을 찾기
- 각 나머지 행의 컬럼/컬럼값을 가져와 별도 행으로 붙이기
- 두 데이터프레임 각각에만 있는 컬럼이어서, 컬럼값이 없을 경우 데이터 없음(NaN)으로 표기하기
3. left : 왼쪽 우선 외부 조인 - SQL의 LEFT OUTER JOIN 과 동일
- 동작 방식
- 왼쪽 데이터프레임의 행을 모두 가져오기
- 왼쪽 데이터프레임의 행에 있는 on의 컬럼값이 동일한 오른쪽 데이터프레임의 행만 컬럼과 함께 가져와 붙이기
- 오른쪽 데이터프레임에 없는 on의 컬럼값을 가진 왼쪽 데이터프레임의 오른쪽 데이터프레임 컬럼들에는 데이터 없음(NaN)으로 표기하기

4. right : 오른쪽 우선 외부 조인 - SQL의 RIGHT OUTER JOIN 과 동일
- 동작 방식
- 오른쪽 데이터프레임의 행을 모두 가져오기
- 오른쪽 데이터프레임의 행에 있는 on의 컬럼값이 동일한 왼쪽 데이터프레임의 행만 컬럼과 함께 가져와 붙이기
- 왼쪽 데이터프레임에 없는 on의 컬럼값을 가진 오른쪽 데이터프레임의 왼쪽 데이터프레임 컬럼들에는 데이터 없음(NaN)으로 표기하기

컬럼이 아닌 인덱스를 기준 컬럼으로 사용하기
- merge(데이터프레임1, 데이터프레임2, left_index=True, right_index=True) : 기준 컬럼을 명시할 수도 있음
### 사전 선언
import pandas as pd
df1 = pd.DataFrame({
'id': [1, 2, 3],
'customer_id': [1, 2, 3],
'customer_name': ['Robert', 'Peter', 'Dave']
}, columns=['id', 'customer_id', 'customer_name'])
df2 = pd.DataFrame({
'id': [1, 2, 4],
'order_id': [100, 200, 300],
'order_date': ['2021-01-21', '2021-02-03', '2020-10-01']
}, columns=['id', 'order_id', 'order_date'])
df1 = df1.set_index('id')
df1

df2 = df2.set_index('id')
df2

pd.merge(df1, df2, left_index=True, right_index=True)

pd.merge(df1, df2, how='outer', left_index=True, right_index=True)

raw data를 pandas와 파이썬으로 그래프 생성
1. 데이터 시각화란?
- 데이터 분석 결과를 쉽게 이해할 수 있도록 시각적으로 표현하고 전달되는 과정
- 탐색적 데이터 분석, 데이터 처리, 데이터 예측 모든 경우, 결과를 알아보기 쉽게 하기 위해 데이터 시각화는 필수적임
- 다양한 시각화 기법 중, 가장 최신의 흥미로운 데이터 시각화 과정을 진행해보기로 함
지금까지 익힌 데이터 처리 기술을 기반으로 데이터 시각화를 위해, raw data를 포멧에 맞추어 변환하여 그래프를 만들어보기

2. 데이터 시각화를 위한 데이터 포멧 이해
- 데이터 시각화를 위해, raw data를 변환해야 함
- 지금까지 익힌 데이터 처리 기술을 사용해서, 데이터를 변환하기로 함
- 필요 데이터
- 국가명, 국기, 날짜별 확진자 수

3. raw data 가져오기
import pandas as pd
PATH = "COVID-19-master/csse_covid_19_data/csse_covid_19_daily_reports/"
doc = pd.read_csv(PATH + "04-01-2020.csv", encoding='utf-8-sig')
doc.head()

import pandas as pd
PATH = "COVID-19-master/csse_covid_19_data/csse_covid_19_daily_reports/"
doc = pd.read_csv(PATH + "03-01-2020.csv", encoding='utf-8-sig')
doc.head()

- 3월 중순 데이터까지는 컬럼명이 Province/State, Country/Region 이고, 이후에는 Province_State, Country_Region 이므로, try except 구문을 사용해서, 데이터 조작
doc = pd.read_csv(PATH + "01-22-2020.csv", encoding='utf-8-sig')
try:
doc = doc[['Province_State', 'Country_Region', 'Confirmed']] # 1. 특정 컬럼만 선택해서 데이터프레임 만들기
except:
doc = doc[['Province/State', 'Country/Region', 'Confirmed']] # 1. 특정 컬럼만 선택해서 데이터프레임 만들기
doc.columns = ['Province_State', 'Country_Region', 'Confirmed']
doc.head()

4. 데이터프레임 데이터 변환
- 특정 컬럼만 선택해서 데이터프레임 만들기
- 특정 컬럼에 없는 데이터 삭제하기
- 특정 컬럼의 데이터 타입 변경하기
import pandas as pd
PATH = "COVID-19-master/csse_covid_19_data/csse_covid_19_daily_reports/"
doc = pd.read_csv(PATH + "01-22-2020.csv", encoding='utf-8-sig')
try:
doc = doc[['Province_State', 'Country_Region', 'Confirmed']] # 1. 특정 컬럼만 선택해서 데이터프레임 만들기
except:
doc = doc[['Province/State', 'Country/Region', 'Confirmed']] # 1. 특정 컬럼만 선택해서 데이터프레임 만들기
doc.columns = ['Province_State', 'Country_Region', 'Confirmed']
doc = doc.dropna(subset=['Confirmed']) # 2. 특정 컬럼에 없는 데이터 삭제하기
doc = doc.astype({'Confirmed': 'int64'}) # 3. 특정 컬럼의 데이터 타입 변경하기
doc.head()

- 국가 정보 가져오기
country_info = pd.read_csv("COVID-19-master/csse_covid_19_data/UID_ISO_FIPS_LookUp_Table.csv", encoding='utf-8-sig')
country_info.head()

- 두 데이터프레임 합쳐보기
test_df = pd.merge(doc, country_info, how='left', on='Country_Region')
test_df.head()

- 잘못 매칭된 국가 정보 확인하기
- iso2 컬럼이 매칭되지 않은 확진자수 국가 확인해보기
test_df.isnull().sum()

nan_rows = test_df[test_df['iso2'].isnull()]
nan_rows.head()

컬럼값 변경하기
- Country_Region 국가 명이 다양한 경우가 많았음
- 각 케이스를 일괄적으로 변경할 키 값이 존재하지 않고, 키가 될 수 있는 컬럼도 다양하고, 각 파일마다 키가 될 수 있는 컬럼이 변경되어, 키 값으로 매칭이 불가 하였음
- 이에 각 케이스를 직접 확인해서, 국가 명을 일관되게 변경할 수 있도록 별도 json 파일 작성
- json 파일 기반으로 국가 명을 일관되게 변경하기로 함
json.load() 함수로 파일로 된 json 데이터를 사전처럼 다룰 수 있음
import json
with open('COVID-19-master/csse_covid_19_data/country_convert.json', 'r', encoding='utf-8-sig') as json_file:
json_data = json.load(json_file)
print (json_data.keys())

apply() 함수 사용법
- apply() 함수를 사용해서, 특정 컬럼값 변경 가능
df = pd.DataFrame({
'영어': [60, 70],
'수학': [100, 50]
}, index = ['Dave', 'David'])
df

def func(df_data):
print (type(df_data))
print (df_data.index)
print (df_data.values)
return df_data
df_func = df.apply(func, axis=0)

df_func = df.apply(func, axis=1)

df = pd.DataFrame({
'영어': [60, 70],
'수학': [100, 50]
}, index = ['Dave', 'David'])
df

def func(df_data):
df_data['영어'] = 80
return df_data
df_func = df.apply(func, axis=1)
df_func

apply() 함수를 사용해서, 국가 컬럼값 변경하기
- 사전 작업 (doc 변수로 데이터프레임 파일 만들기)
import pandas as pd
doc = pd.read_csv(PATH + "01-22-2020.csv", encoding='utf-8-sig')
try:
doc = doc[['Province_State', 'Country_Region', 'Confirmed']] # 1. 특정 컬럼만 선택해서 데이터프레임 만들기
except:
doc = doc[['Province/State', 'Country/Region', 'Confirmed']] # 1. 특정 컬럼만 선택해서 데이터프레임 만들기
doc.columns = ['Province_State', 'Country_Region', 'Confirmed']
doc = doc.dropna(subset=['Confirmed']) # 2. 특정 컬럼에 없는 데이터 삭제하기
doc = doc.astype({'Confirmed': 'int64'}) # 3. 특정 컬럼의 데이터 타입 변경하기
doc.head()

- 변경할 국가명을 가지고 있는 json 파일 읽기
import json
with open('COVID-19-master/csse_covid_19_data/country_convert.json', 'r', encoding='utf-8-sig') as json_file:
json_data = json.load(json_file)
print (json_data.keys())

- Country_Region 이라는 컬럼값을 확인해서, 국가명이 다르게 기재되어 있을 경우에만, 지정한 국가명으로 변경
def func(row):
if row['Country_Region'] in json_data:
row['Country_Region'] = json_data[row['Country_Region']]
return row
doc = doc.apply(func, axis=1)
doc.head()

참고: 파일명으로 데이터 변환하기
- lstrip(): 앞에(왼쪽에)서 특정 데이터 삭제하기, rstrip(): 뒤에(오른쪽에)서 특정 데이터 삭제하기
- replace(변경전데이터, 변경후데이터): 문자열에서 변경전데이터 를 변경후데이터 로 변경
data = "01-22-2020.csv"
date_column = data.split(".")[0].lstrip('0').replace('-', '/')
date_column
'1/22/2020’
data = "01-22-2020.csv"
data.split('.')[0].lstrip("0").replace('-', '/')
'1/22/2020’
doc.columns
Index(['Province_State', 'Country_Region', 'Confirmed'], dtype='object')
doc.head()

5. 중복 데이터 합치기
groupby() : 그룹별로 데이터를 집계하는 함수
- 동일한 컬럼값으로 묶어서 통계 또는 평균등을 확인할 수 있음
df = pd.DataFrame({
'성별': ['남', '남', '남'],
'이름': ['David', 'Dave', 'Dave'],
'수학': [100, 50, 80],
'국어': [80, 70, 50]
})
df

df.groupby('이름').mean()

- 국가별 총 확진자수 구하기
import pandas as pd
doc = pd.read_csv(PATH + "01-22-2020.csv", encoding='utf-8-sig')
try:
doc = doc[['Province_State', 'Country_Region', 'Confirmed']] # 1. 특정 컬럼만 선택해서 데이터프레임 만들기
except:
doc = doc[['Province/State', 'Country/Region', 'Confirmed']] # 1. 특정 컬럼만 선택해서 데이터프레임 만들기
doc.columns = ['Province_State', 'Country_Region', 'Confirmed']
doc = doc.dropna(subset=['Confirmed']) # 2. 특정 컬럼에 없는 데이터 삭제하기
doc = doc.astype({'Confirmed': 'int64'}) # 3. 특정 컬럼의 데이터 타입 변경하기
doc.head()

doc.groupby('Country_Region').sum() # 4. Country_Region 컬럼값이 동일한 케이스를 그룹화해서, 각 그룹별 합계 확인하기

6. 데이터 전처리하기
지금까지의 과정을 모두 한데 모아서, 함수로 만들기
- csv 파일 읽기
- 'Country_Region', 'Confirmed' 두 개의 컬럼만 가져오기
- 'Confirmed' 에 데이터가 없는 행 삭제하기
- 'Country_Region'의 국가명을 여러 파일에 일관되게 변경하기
- 'Confirmed' 데이터 타입을 int64(정수) 로 변경
- 'Country_Region' 를 기준으로 중복된 데이터를 합치기
- 파일명을 기반으로 날짜 문자열 변환하고, 'Confirmed' 컬럼명 변경하기
import json
with open('COVID-19-master/csse_covid_19_data/country_convert.json', 'r', encoding='utf-8-sig') as json_file:
json_data = json.load(json_file)
def country_name_convert(row):
if row['Country_Region'] in json_data:
return json_data[row['Country_Region']]
return row['Country_Region']
def create_dateframe(filename):
doc = pd.read_csv(PATH + filename, encoding='utf-8-sig') # 1. csv 파일 읽기
try:
doc = doc[['Country_Region', 'Confirmed']] # 2. 특정 컬럼만 선택해서 데이터프레임 만들기
except:
doc = doc[['Country/Region', 'Confirmed']] # 2. 특정 컬럼만 선택해서 데이터프레임 만들기
doc.columns = ['Country_Region', 'Confirmed']
doc = doc.dropna(subset=['Confirmed']) # 3. 특정 컬럼에 없는 데이터 삭제하기
doc['Country_Region'] = doc.apply(country_name_convert, axis=1) # 4. 'Country_Region'의 국가명을 여러 파일에 일관되게 변경하기
doc = doc.astype({'Confirmed': 'int64'}) # 5. 특정 컬럼의 데이터 타입 변경하기
doc = doc.groupby('Country_Region').sum() # 6. 특정 컬럼으로 중복된 데이터를 합치기
# 7. 파일명을 기반으로 날짜 문자열 변환하고, 'Confirmed' 컬럼명 변경하기
date_column = filename.split(".")[0].lstrip('0').replace('-', '/')
doc.columns = [date_column]
return doc
테스트해보기
doc1 = create_dateframe("01-22-2020.csv")
doc2 = create_dateframe("04-01-2020.csv")
doc1.head()

doc2.head()

데이터프레임 합치기
doc = pd.merge(doc1, doc2, how='outer', left_index=True, right_index=True)
doc.head()

없는 데이터는 0으로 값 대체하기
doc = doc.fillna(0)
doc

참고: 특정 폴더 파일 리스트 확인하기
- split() 함수를 사용해서 특정 확장자를 가진 파일 리스트만 추출 가능
- 문자열변수.split('.') 은 ['파일명', '확장자'] 와 같은 리스트가 반환되므로, 문자열변수.split('.')[-1] 을 통해, 이 중에서 마지막 아이템을 선택하면 됨
import os
PATH = 'COVID-19-master/csse_covid_19_data/csse_covid_19_daily_reports/'
file_list = os.listdir(PATH)
csv_list = list()
for file in file_list:
if file.split(".")[-1] == 'csv':
csv_list.append(file)
print (csv_list)

참고: 리스트 정렬
- 리스트변수.sort() : 오름차순 정렬 (디폴트)
- 리스트변수.sort(reverse=True) : 내림차순 정렬
csv_list.sort()
csv_list

7. 여러 데이터 수집, 전처리해서, 하나의 데이터프레임 만들기
- 필요한 파일 리스트만 추출하기
- 파일 리스트 정렬하기
- 데이터프레임 전처리하기 (별도 create_dateframe() 함수)
- 데이터프레임 합치기
최종 코드
import json
import pandas as pd
with open('COVID-19-master/csse_covid_19_data/country_convert.json', 'r', encoding='utf-8-sig') as json_file:
json_data = json.load(json_file)
def country_name_convert(row):
if row['Country_Region'] in json_data:
return json_data[row['Country_Region']]
return row['Country_Region']
def create_dateframe(filename):
doc = pd.read_csv(PATH + filename, encoding='utf-8-sig') # 1. csv 파일 읽기
try:
doc = doc[['Country_Region', 'Confirmed']] # 2. 특정 컬럼만 선택해서 데이터프레임 만들기
except:
doc = doc[['Country/Region', 'Confirmed']] # 2. 특정 컬럼만 선택해서 데이터프레임 만들기
doc.columns = ['Country_Region', 'Confirmed']
doc = doc.dropna(subset=['Confirmed']) # 3. 특정 컬럼에 없는 데이터 삭제하기
doc['Country_Region'] = doc.apply(country_name_convert, axis=1) # 4. 'Country_Region'의 국가명을 여러 파일에 일관되게 변경하기
doc = doc.astype({'Confirmed': 'int64'}) # 5. 특정 컬럼의 데이터 타입 변경하기
doc = doc.groupby('Country_Region').sum() # 6. 특정 컬럼으로 중복된 데이터를 합치기
# 7. 파일명을 기반으로 날짜 문자열 변환하고, 'Confirmed' 컬럼명 변경하기
date_column = filename.split(".")[0].lstrip('0').replace('-', '/')
doc.columns = [date_column]
return doc
import os
def generate_dateframe_by_path(PATH):
file_list, csv_list = os.listdir(PATH), list()
first_doc = True
for file in file_list:
if file.split(".")[-1] == 'csv':
csv_list.append(file)
csv_list.sort()
for file in csv_list:
doc = create_dateframe(file)
if first_doc:
final_doc, first_doc = doc, False
else:
final_doc = pd.merge(final_doc, doc, how='outer', left_index=True, right_index=True)
final_doc = final_doc.fillna(0)
return final_doc
PATH = 'COVID-19-master/csse_covid_19_data/csse_covid_19_daily_reports/'
doc = generate_dateframe_by_path(PATH)
doc

참고: 데이터 타입 변환이 가능한 모든 열의 데이터 타입 변경
pd.astype()
- object 는 파이썬의 str 또는 혼용 데이터 타입 (문자열)
- int64 는 파이썬의 int (정수)
- float64 는 파이썬의 float (부동소숫점)
- bool 는 파이썬의 bool (True 또는 False 값을 가지는 boolean)
doc = doc.astype('int64')
doc

pandas 라이브러리로 csv 파일 쓰기
- pandas dataframe 데이터를 csv 파일로 저장하기 위해, to_csv() 함수 사용
doc.to_csv("00_data/students_default.csv")
- encoding 옵션 사용 가능
doc.to_csv("COVID-19-master/final_df.csv")
doc.to_csv("00_data/students_default.csv", encoding='utf-8-sig')
- 최종 데이터에 날짜가 2020 1/1 2021 1/1 2022 1/1 이런 식으로 되어 있어서 수정하였다
- 방법 1
- doc = doc.reindex(sorted(doc.columns, key=pd.to_datetime), axis=1)

- 방법 2
def generate_dateframe_by_path(PATH):
file_list, csv_list = os.listdir(PATH), list()
first_doc = True
for file in file_list:
if file.split(".")[-1] == 'csv':
csv_list.append(file)
#데이터 정렬 코드
## 방법1
csv_df = pd.DataFrame(csv_list)
csv_df
csv_df['year'] = csv_df[0].str.split('.').str[0].str.split('-').str[-1]
csv_df['day'] = csv_df[0].str.split('.').str[0].str.split('-').str[-2]
csv_df['month'] = csv_df[0].str.split('.').str[0].str.split('-').str[-3]
csv_df = csv_df.sort_values(['year','month','day'])
csv_list = list(csv_df[0])
##방법2
csv_list = sorted(csv_list,key=lambda x: (x[6:10],x[:2],x[3:5]))
##방법3
csv_list = sorted(csv_list,key=lambda x: pd.to_datetime(x.split('.')[0],format='%m-%d-%Y'))

- 방법3
def generate_dateframe_by_path(PATH):
file_list, csv_list = os.listdir(PATH), list()
first_doc = True
for file in file_list:
if file.split(".")[-1] == 'csv':
csv_list.append(file)
csv_list.sort()
def extract_date(filename):
date_part = filename.split('.')[0] # 파일명에서 날짜 부분 추출
return datetime.strptime(date_part, '%m-%d-%Y')
# 날짜를 추출하고 정렬합니다.
sorted_dates = sorted(csv_list, key=extract_date)

'빅데이터 분석가 양성과정 > Python' 카테고리의 다른 글
pandas - brazil ecommerce dataset ( 1 ) (0) | 2024.07.09 |
---|---|
pandas_COVID-19 ( 3 ) (0) | 2024.07.09 |
pandas_COVID-19 ( 1 ) (0) | 2024.07.09 |
Pandas (0) | 2024.07.09 |
Matplotlib ( 2 ) (0) | 2024.07.09 |
Merge_Concat
두 데이터 프레임 연결하기
import pandas as pd
df1 = pd.DataFrame({ 'id': [1, 2, 3], 'customer_id': [1, 2, 3], 'customer_name': ['Robert', 'Peter', 'Dave']}, columns=['id', 'customer_id', 'customer_name'])df1

df2 = pd.DataFrame({ 'id': [1, 2, 4], 'order_id': [100, 200, 300], 'order_date': ['2021-01-21', '2021-02-03', '2020-10-01']}, columns=['id', 'order_id', 'order_date'])df2

concat()
- 두 데이터프레임을 연결해서 하나의 데이터프레임으로 만들 수 있음
- 두 데이터프레임을 위/아래 또는 왼쪽/오른쪽으로 연결하기만 함
- pd.concat([데이터프레임1, 데이터프레임2])
pd.concat([df1, df2])

axis: 0 이면(디폴트) 위에서 아래로 합치고, 1 이면 왼쪽과 오른쪽으로 합침
doc = pd.concat([df1, df2], axis=1)doc.head()

두 데이터 프레임 합치기
merge()
- merge(데이터프레임1, 데이터프레임2) : 두 데이터프레임에 동일한 이름을 가진 컬럼을 기준으로 두 데이터프레임을 합침
pd.merge(df1, df2)

- merge(데이터프레임1, 데이터프레임2, on=기준컬럼명) : 기준 컬럼을 명시할 수도 있음
pd.merge(df1, df2, on='id')

merge() 를 통해 어떻게 두 데이터프레임을 결함시킬 것인가에 대해 보다 상세한 기능을 제공함
- merge(데이터프레임1, 데이터프레임2, how=결합방법)
- 결합방법
- inner : 내부 조인 - SQL의 INNER JOIN 과 동일
- outer : 완전 외부 조인 - SQL의 OUTER JOIN 과 동일
- left : 왼쪽 우선 외부 조인 - SQL의 LEFT OUTER JOIN 과 동일
- right : 오른쪽 우선 외부 조인 - SQL의 RIGHT OUTER JOIN 과 동일
merge() 함수는 SQL의 JOIN 기능과 동일함
- SQL JOIN: 두 개 이상의 테이블로부터 필요한 데이터를 연결해 하나의 포괄적인 구조로 결합시키는 연산
1. inner : 내부 조인 - SQL의 INNER JOIN 과 동일 (디폴트)
- 동작 방식
- on의 컬럼값이 두 데이터프레임에서 동일한 행 찾기
- 각 동일한 행의 컬럼/컬럼값만 가져오기

2. outer : 완전 외부 조인 - SQL의 OUTER JOIN 과 동일
- 동작 방식
- on의 컬럼값이 두 데이터프레임에서 동일한 행 찾기
- 각 동일한 행의 컬럼/컬럼값 가져와 붙이기
- 각 데이터프레임에서 on의 컬럼값이 다른 나머지 행을 찾기
- 각 나머지 행의 컬럼/컬럼값을 가져와 별도 행으로 붙이기
- 두 데이터프레임 각각에만 있는 컬럼이어서, 컬럼값이 없을 경우 데이터 없음(NaN)으로 표기하기
3. left : 왼쪽 우선 외부 조인 - SQL의 LEFT OUTER JOIN 과 동일
- 동작 방식
- 왼쪽 데이터프레임의 행을 모두 가져오기
- 왼쪽 데이터프레임의 행에 있는 on의 컬럼값이 동일한 오른쪽 데이터프레임의 행만 컬럼과 함께 가져와 붙이기
- 오른쪽 데이터프레임에 없는 on의 컬럼값을 가진 왼쪽 데이터프레임의 오른쪽 데이터프레임 컬럼들에는 데이터 없음(NaN)으로 표기하기

4. right : 오른쪽 우선 외부 조인 - SQL의 RIGHT OUTER JOIN 과 동일
- 동작 방식
- 오른쪽 데이터프레임의 행을 모두 가져오기
- 오른쪽 데이터프레임의 행에 있는 on의 컬럼값이 동일한 왼쪽 데이터프레임의 행만 컬럼과 함께 가져와 붙이기
- 왼쪽 데이터프레임에 없는 on의 컬럼값을 가진 오른쪽 데이터프레임의 왼쪽 데이터프레임 컬럼들에는 데이터 없음(NaN)으로 표기하기

컬럼이 아닌 인덱스를 기준 컬럼으로 사용하기
- merge(데이터프레임1, 데이터프레임2, left_index=True, right_index=True) : 기준 컬럼을 명시할 수도 있음
### 사전 선언import pandas as pddf1 = pd.DataFrame({ 'id': [1, 2, 3], 'customer_id': [1, 2, 3], 'customer_name': ['Robert', 'Peter', 'Dave']}, columns=['id', 'customer_id', 'customer_name'])df2 = pd.DataFrame({ 'id': [1, 2, 4], 'order_id': [100, 200, 300], 'order_date': ['2021-01-21', '2021-02-03', '2020-10-01']}, columns=['id', 'order_id', 'order_date'])
df1 = df1.set_index('id')df1

df2 = df2.set_index('id')df2

pd.merge(df1, df2, left_index=True, right_index=True)

pd.merge(df1, df2, how='outer', left_index=True, right_index=True)

raw data를 pandas와 파이썬으로 그래프 생성
1. 데이터 시각화란?
- 데이터 분석 결과를 쉽게 이해할 수 있도록 시각적으로 표현하고 전달되는 과정
- 탐색적 데이터 분석, 데이터 처리, 데이터 예측 모든 경우, 결과를 알아보기 쉽게 하기 위해 데이터 시각화는 필수적임
- 다양한 시각화 기법 중, 가장 최신의 흥미로운 데이터 시각화 과정을 진행해보기로 함
지금까지 익힌 데이터 처리 기술을 기반으로 데이터 시각화를 위해, raw data를 포멧에 맞추어 변환하여 그래프를 만들어보기

2. 데이터 시각화를 위한 데이터 포멧 이해
- 데이터 시각화를 위해, raw data를 변환해야 함
- 지금까지 익힌 데이터 처리 기술을 사용해서, 데이터를 변환하기로 함
- 필요 데이터
- 국가명, 국기, 날짜별 확진자 수

3. raw data 가져오기
import pandas as pdPATH = "COVID-19-master/csse_covid_19_data/csse_covid_19_daily_reports/"doc = pd.read_csv(PATH + "04-01-2020.csv", encoding='utf-8-sig')doc.head()

import pandas as pdPATH = "COVID-19-master/csse_covid_19_data/csse_covid_19_daily_reports/"doc = pd.read_csv(PATH + "03-01-2020.csv", encoding='utf-8-sig')doc.head()

- 3월 중순 데이터까지는 컬럼명이 Province/State, Country/Region 이고, 이후에는 Province_State, Country_Region 이므로, try except 구문을 사용해서, 데이터 조작
doc = pd.read_csv(PATH + "01-22-2020.csv", encoding='utf-8-sig')try: doc = doc[['Province_State', 'Country_Region', 'Confirmed']] # 1. 특정 컬럼만 선택해서 데이터프레임 만들기except: doc = doc[['Province/State', 'Country/Region', 'Confirmed']] # 1. 특정 컬럼만 선택해서 데이터프레임 만들기 doc.columns = ['Province_State', 'Country_Region', 'Confirmed'] doc.head()

4. 데이터프레임 데이터 변환
- 특정 컬럼만 선택해서 데이터프레임 만들기
- 특정 컬럼에 없는 데이터 삭제하기
- 특정 컬럼의 데이터 타입 변경하기
import pandas as pdPATH = "COVID-19-master/csse_covid_19_data/csse_covid_19_daily_reports/"doc = pd.read_csv(PATH + "01-22-2020.csv", encoding='utf-8-sig')try: doc = doc[['Province_State', 'Country_Region', 'Confirmed']] # 1. 특정 컬럼만 선택해서 데이터프레임 만들기except: doc = doc[['Province/State', 'Country/Region', 'Confirmed']] # 1. 특정 컬럼만 선택해서 데이터프레임 만들기 doc.columns = ['Province_State', 'Country_Region', 'Confirmed']doc = doc.dropna(subset=['Confirmed']) # 2. 특정 컬럼에 없는 데이터 삭제하기doc = doc.astype({'Confirmed': 'int64'}) # 3. 특정 컬럼의 데이터 타입 변경하기doc.head()

- 국가 정보 가져오기
country_info = pd.read_csv("COVID-19-master/csse_covid_19_data/UID_ISO_FIPS_LookUp_Table.csv", encoding='utf-8-sig')country_info.head()

- 두 데이터프레임 합쳐보기
test_df = pd.merge(doc, country_info, how='left', on='Country_Region')test_df.head()

- 잘못 매칭된 국가 정보 확인하기
- iso2 컬럼이 매칭되지 않은 확진자수 국가 확인해보기
test_df.isnull().sum()

nan_rows = test_df[test_df['iso2'].isnull()]nan_rows.head()

컬럼값 변경하기
- Country_Region 국가 명이 다양한 경우가 많았음
- 각 케이스를 일괄적으로 변경할 키 값이 존재하지 않고, 키가 될 수 있는 컬럼도 다양하고, 각 파일마다 키가 될 수 있는 컬럼이 변경되어, 키 값으로 매칭이 불가 하였음
- 이에 각 케이스를 직접 확인해서, 국가 명을 일관되게 변경할 수 있도록 별도 json 파일 작성
- json 파일 기반으로 국가 명을 일관되게 변경하기로 함
json.load() 함수로 파일로 된 json 데이터를 사전처럼 다룰 수 있음
import jsonwith open('COVID-19-master/csse_covid_19_data/country_convert.json', 'r', encoding='utf-8-sig') as json_file: json_data = json.load(json_file) print (json_data.keys())

apply() 함수 사용법
- apply() 함수를 사용해서, 특정 컬럼값 변경 가능
df = pd.DataFrame({ '영어': [60, 70], '수학': [100, 50]}, index = ['Dave', 'David'])df

def func(df_data): print (type(df_data)) print (df_data.index) print (df_data.values) return df_data
df_func = df.apply(func, axis=0)

df_func = df.apply(func, axis=1)

df = pd.DataFrame({ '영어': [60, 70], '수학': [100, 50]}, index = ['Dave', 'David'])df

def func(df_data): df_data['영어'] = 80 return df_datadf_func = df.apply(func, axis=1)df_func

apply() 함수를 사용해서, 국가 컬럼값 변경하기
- 사전 작업 (doc 변수로 데이터프레임 파일 만들기)
import pandas as pddoc = pd.read_csv(PATH + "01-22-2020.csv", encoding='utf-8-sig')try: doc = doc[['Province_State', 'Country_Region', 'Confirmed']] # 1. 특정 컬럼만 선택해서 데이터프레임 만들기except: doc = doc[['Province/State', 'Country/Region', 'Confirmed']] # 1. 특정 컬럼만 선택해서 데이터프레임 만들기 doc.columns = ['Province_State', 'Country_Region', 'Confirmed']doc = doc.dropna(subset=['Confirmed']) # 2. 특정 컬럼에 없는 데이터 삭제하기doc = doc.astype({'Confirmed': 'int64'}) # 3. 특정 컬럼의 데이터 타입 변경하기doc.head()

- 변경할 국가명을 가지고 있는 json 파일 읽기
import jsonwith open('COVID-19-master/csse_covid_19_data/country_convert.json', 'r', encoding='utf-8-sig') as json_file: json_data = json.load(json_file) print (json_data.keys())

- Country_Region 이라는 컬럼값을 확인해서, 국가명이 다르게 기재되어 있을 경우에만, 지정한 국가명으로 변경
def func(row): if row['Country_Region'] in json_data: row['Country_Region'] = json_data[row['Country_Region']] return row
doc = doc.apply(func, axis=1)doc.head()

참고: 파일명으로 데이터 변환하기
- lstrip(): 앞에(왼쪽에)서 특정 데이터 삭제하기, rstrip(): 뒤에(오른쪽에)서 특정 데이터 삭제하기
- replace(변경전데이터, 변경후데이터): 문자열에서 변경전데이터 를 변경후데이터 로 변경
data = "01-22-2020.csv"date_column = data.split(".")[0].lstrip('0').replace('-', '/')date_column
'1/22/2020’
data = "01-22-2020.csv"data.split('.')[0].lstrip("0").replace('-', '/')
'1/22/2020’
doc.columns
Index(['Province_State', 'Country_Region', 'Confirmed'], dtype='object')
doc.head()

5. 중복 데이터 합치기
groupby() : 그룹별로 데이터를 집계하는 함수
- 동일한 컬럼값으로 묶어서 통계 또는 평균등을 확인할 수 있음
df = pd.DataFrame({ '성별': ['남', '남', '남'], '이름': ['David', 'Dave', 'Dave'], '수학': [100, 50, 80], '국어': [80, 70, 50] })df

df.groupby('이름').mean()

- 국가별 총 확진자수 구하기
import pandas as pddoc = pd.read_csv(PATH + "01-22-2020.csv", encoding='utf-8-sig')try: doc = doc[['Province_State', 'Country_Region', 'Confirmed']] # 1. 특정 컬럼만 선택해서 데이터프레임 만들기except: doc = doc[['Province/State', 'Country/Region', 'Confirmed']] # 1. 특정 컬럼만 선택해서 데이터프레임 만들기 doc.columns = ['Province_State', 'Country_Region', 'Confirmed']doc = doc.dropna(subset=['Confirmed']) # 2. 특정 컬럼에 없는 데이터 삭제하기doc = doc.astype({'Confirmed': 'int64'}) # 3. 특정 컬럼의 데이터 타입 변경하기doc.head()

doc.groupby('Country_Region').sum() # 4. Country_Region 컬럼값이 동일한 케이스를 그룹화해서, 각 그룹별 합계 확인하기

6. 데이터 전처리하기
지금까지의 과정을 모두 한데 모아서, 함수로 만들기
- csv 파일 읽기
- 'Country_Region', 'Confirmed' 두 개의 컬럼만 가져오기
- 'Confirmed' 에 데이터가 없는 행 삭제하기
- 'Country_Region'의 국가명을 여러 파일에 일관되게 변경하기
- 'Confirmed' 데이터 타입을 int64(정수) 로 변경
- 'Country_Region' 를 기준으로 중복된 데이터를 합치기
- 파일명을 기반으로 날짜 문자열 변환하고, 'Confirmed' 컬럼명 변경하기
import jsonwith open('COVID-19-master/csse_covid_19_data/country_convert.json', 'r', encoding='utf-8-sig') as json_file: json_data = json.load(json_file)def country_name_convert(row): if row['Country_Region'] in json_data: return json_data[row['Country_Region']] return row['Country_Region']def create_dateframe(filename): doc = pd.read_csv(PATH + filename, encoding='utf-8-sig') # 1. csv 파일 읽기 try: doc = doc[['Country_Region', 'Confirmed']] # 2. 특정 컬럼만 선택해서 데이터프레임 만들기 except: doc = doc[['Country/Region', 'Confirmed']] # 2. 특정 컬럼만 선택해서 데이터프레임 만들기 doc.columns = ['Country_Region', 'Confirmed'] doc = doc.dropna(subset=['Confirmed']) # 3. 특정 컬럼에 없는 데이터 삭제하기 doc['Country_Region'] = doc.apply(country_name_convert, axis=1) # 4. 'Country_Region'의 국가명을 여러 파일에 일관되게 변경하기 doc = doc.astype({'Confirmed': 'int64'}) # 5. 특정 컬럼의 데이터 타입 변경하기 doc = doc.groupby('Country_Region').sum() # 6. 특정 컬럼으로 중복된 데이터를 합치기 # 7. 파일명을 기반으로 날짜 문자열 변환하고, 'Confirmed' 컬럼명 변경하기 date_column = filename.split(".")[0].lstrip('0').replace('-', '/') doc.columns = [date_column] return doc
테스트해보기
doc1 = create_dateframe("01-22-2020.csv")doc2 = create_dateframe("04-01-2020.csv")
doc1.head()

doc2.head()

데이터프레임 합치기
doc = pd.merge(doc1, doc2, how='outer', left_index=True, right_index=True)doc.head()

없는 데이터는 0으로 값 대체하기
doc = doc.fillna(0)doc

참고: 특정 폴더 파일 리스트 확인하기
- split() 함수를 사용해서 특정 확장자를 가진 파일 리스트만 추출 가능
- 문자열변수.split('.') 은 ['파일명', '확장자'] 와 같은 리스트가 반환되므로, 문자열변수.split('.')[-1] 을 통해, 이 중에서 마지막 아이템을 선택하면 됨
import osPATH = 'COVID-19-master/csse_covid_19_data/csse_covid_19_daily_reports/'file_list = os.listdir(PATH)csv_list = list()for file in file_list: if file.split(".")[-1] == 'csv': csv_list.append(file)print (csv_list)

참고: 리스트 정렬
- 리스트변수.sort() : 오름차순 정렬 (디폴트)
- 리스트변수.sort(reverse=True) : 내림차순 정렬
csv_list.sort()csv_list

7. 여러 데이터 수집, 전처리해서, 하나의 데이터프레임 만들기
- 필요한 파일 리스트만 추출하기
- 파일 리스트 정렬하기
- 데이터프레임 전처리하기 (별도 create_dateframe() 함수)
- 데이터프레임 합치기
최종 코드
import jsonimport pandas as pdwith open('COVID-19-master/csse_covid_19_data/country_convert.json', 'r', encoding='utf-8-sig') as json_file: json_data = json.load(json_file)def country_name_convert(row): if row['Country_Region'] in json_data: return json_data[row['Country_Region']] return row['Country_Region']def create_dateframe(filename): doc = pd.read_csv(PATH + filename, encoding='utf-8-sig') # 1. csv 파일 읽기 try: doc = doc[['Country_Region', 'Confirmed']] # 2. 특정 컬럼만 선택해서 데이터프레임 만들기 except: doc = doc[['Country/Region', 'Confirmed']] # 2. 특정 컬럼만 선택해서 데이터프레임 만들기 doc.columns = ['Country_Region', 'Confirmed'] doc = doc.dropna(subset=['Confirmed']) # 3. 특정 컬럼에 없는 데이터 삭제하기 doc['Country_Region'] = doc.apply(country_name_convert, axis=1) # 4. 'Country_Region'의 국가명을 여러 파일에 일관되게 변경하기 doc = doc.astype({'Confirmed': 'int64'}) # 5. 특정 컬럼의 데이터 타입 변경하기 doc = doc.groupby('Country_Region').sum() # 6. 특정 컬럼으로 중복된 데이터를 합치기 # 7. 파일명을 기반으로 날짜 문자열 변환하고, 'Confirmed' 컬럼명 변경하기 date_column = filename.split(".")[0].lstrip('0').replace('-', '/') doc.columns = [date_column] return doc
import osdef generate_dateframe_by_path(PATH): file_list, csv_list = os.listdir(PATH), list() first_doc = True for file in file_list: if file.split(".")[-1] == 'csv': csv_list.append(file) csv_list.sort() for file in csv_list: doc = create_dateframe(file) if first_doc: final_doc, first_doc = doc, False else: final_doc = pd.merge(final_doc, doc, how='outer', left_index=True, right_index=True) final_doc = final_doc.fillna(0) return final_doc
PATH = 'COVID-19-master/csse_covid_19_data/csse_covid_19_daily_reports/'doc = generate_dateframe_by_path(PATH)doc

참고: 데이터 타입 변환이 가능한 모든 열의 데이터 타입 변경
pd.astype()
- object 는 파이썬의 str 또는 혼용 데이터 타입 (문자열)
- int64 는 파이썬의 int (정수)
- float64 는 파이썬의 float (부동소숫점)
- bool 는 파이썬의 bool (True 또는 False 값을 가지는 boolean)
doc = doc.astype('int64')doc

pandas 라이브러리로 csv 파일 쓰기
- pandas dataframe 데이터를 csv 파일로 저장하기 위해, to_csv() 함수 사용
doc.to_csv("00_data/students_default.csv")
- encoding 옵션 사용 가능
doc.to_csv("COVID-19-master/final_df.csv")doc.to_csv("00_data/students_default.csv", encoding='utf-8-sig')
- 최종 데이터에 날짜가 2020 1/1 2021 1/1 2022 1/1 이런 식으로 되어 있어서 수정하였다
- 방법 1
- doc = doc.reindex(sorted(doc.columns, key=pd.to_datetime), axis=1)

- 방법 2
def generate_dateframe_by_path(PATH): file_list, csv_list = os.listdir(PATH), list() first_doc = True for file in file_list: if file.split(".")[-1] == 'csv': csv_list.append(file) #데이터 정렬 코드 ## 방법1 csv_df = pd.DataFrame(csv_list) csv_df csv_df['year'] = csv_df[0].str.split('.').str[0].str.split('-').str[-1] csv_df['day'] = csv_df[0].str.split('.').str[0].str.split('-').str[-2] csv_df['month'] = csv_df[0].str.split('.').str[0].str.split('-').str[-3] csv_df = csv_df.sort_values(['year','month','day']) csv_list = list(csv_df[0]) ##방법2 csv_list = sorted(csv_list,key=lambda x: (x[6:10],x[:2],x[3:5])) ##방법3 csv_list = sorted(csv_list,key=lambda x: pd.to_datetime(x.split('.')[0],format='%m-%d-%Y'))

- 방법3
def generate_dateframe_by_path(PATH): file_list, csv_list = os.listdir(PATH), list() first_doc = True for file in file_list: if file.split(".")[-1] == 'csv': csv_list.append(file) csv_list.sort() def extract_date(filename): date_part = filename.split('.')[0] # 파일명에서 날짜 부분 추출 return datetime.strptime(date_part, '%m-%d-%Y')# 날짜를 추출하고 정렬합니다. sorted_dates = sorted(csv_list, key=extract_date)

'빅데이터 분석가 양성과정 > Python' 카테고리의 다른 글
pandas - brazil ecommerce dataset ( 1 ) (0) | 2024.07.09 |
---|---|
pandas_COVID-19 ( 3 ) (0) | 2024.07.09 |
pandas_COVID-19 ( 1 ) (0) | 2024.07.09 |
Pandas (0) | 2024.07.09 |
Matplotlib ( 2 ) (0) | 2024.07.09 |