2.2. 데이터프레임의 요약#
이 절에서는 데이터프레임을 이용하여 새로운 정보를 만드는 방법을 배운다. 살펴볼 내용은 다음과 같다.
데이터 불러오기
열에 대한 요약 통계
해당 연도 요약 통계
해당 시도 요약 통계
데이터 내보내기
고용산재보험 데이터#
이제 실제 데이터인 고용, 산재의 데이터(음식_사업장.csv)을 불러오자.
불러올 데이터는 2017년부터 2021년의 5년간 시도별 고용보험과 산재보험을 가입한 음식 사업장 수 데이터이다.
pandas는 지금 다루는 데이터 프레임을 처리하기 위한 라이브러리입니다.
밑에 코드는 함수를 쓸 때 pandas를 계속 입력하기 번거로우니 pd로 간략하게 지정하면서 불러옵니다.
import pandas as pd
변수를 지정할 땐, 다른 사람이 어떤 것을 의미하는지 쉽게 파악할 수 있도록 변수를 지정하는 것이 좋습니다. 저희가 불러오는 데이터가 음식 사업장 수 이므로 변수 이름은 food data를 지칭하는 food_dat으로 설정하겠습니다.
food_dat = pd.read_csv("https://uos-bigdata.github.io/lab_data/docs/assets/data_lab_bokji/data_food.csv")
food_dat
| 시도 | 연도 | 산재_음식사업장수 | 고용_음식사업장수 | |
|---|---|---|---|---|
| 0 | 광주 | 2017.0 | 796 | 801 |
| 1 | 광주 | 2018.0 | 1121 | 1136 |
| 2 | 광주 | 2019.0 | 1674 | 1679 |
| 3 | 광주 | 2020.0 | 1757 | 1763 |
| 4 | 광주 | 2021.0 | 1727 | 1734 |
| 5 | 대구 | 2017.0 | 1367 | 1375 |
| 6 | 대구 | 2018.0 | 1739 | 1749 |
| 7 | 대구 | 2019.0 | 2523 | 2531 |
| 8 | 대구 | 2020.0 | 2428 | 2434 |
| 9 | 대구 | 2021.0 | 2619 | 2624 |
| 10 | 대전 | 2017.0 | 933 | 927 |
| 11 | 대전 | 2018.0 | 1093 | 1131 |
| 12 | 대전 | 2019.0 | 1588 | 1606 |
| 13 | 대전 | 2020.0 | 1767 | 1781 |
| 14 | 대전 | 2021.0 | 1634 | 1652 |
| 15 | 부산 | 2017.0 | 1713 | 1720 |
| 16 | 부산 | 2018.0 | 2159 | 2168 |
| 17 | 부산 | 2019.0 | 3205 | 3215 |
| 18 | 부산 | 2020.0 | 3508 | 3508 |
| 19 | 부산 | 2021.0 | 3829 | 3836 |
| 20 | 서울 | 2017.0 | 6069 | 6117 |
| 21 | 서울 | 2018.0 | 7967 | 8000 |
| 22 | 서울 | 2019.0 | 10576 | 10596 |
| 23 | 서울 | 2020.0 | 10612 | 10631 |
| 24 | 서울 | 2021.0 | 10752 | 10796 |
| 25 | 울산 | 2017.0 | 541 | 541 |
| 26 | 울산 | 2018.0 | 651 | 654 |
| 27 | 울산 | 2019.0 | 996 | 998 |
| 28 | 울산 | 2020.0 | 1137 | 1138 |
| 29 | 울산 | 2021.0 | 1046 | 1048 |
| 30 | 인천 | 2017.0 | 1319 | 1318 |
| 31 | 인천 | 2018.0 | 1817 | 1835 |
| 32 | 인천 | 2019.0 | 2718 | 2731 |
| 33 | 인천 | 2020.0 | 2886 | 2892 |
| 34 | 인천 | 2021.0 | 2891 | 2898 |
열의 요약 통계#
불러온 데이터를 간략하게 봅니다.
참고로 연도는 범주형자료이기 때문에 통계량으로써는 의미가 없습니다. 그래서 연도는 지우고 평균을 구해보겠습니다.
이때, drop method를 이용하고, axis option을 이용하여 “column” 을 지정해줍니다.
food_sum = food_dat.drop(['연도'], axis=1)
describe method를 이용해서 기초통계량들을 확인할 수 있습니다.
food_sum.describe()
| 산재_음식사업장수 | 고용_음식사업장수 | |
|---|---|---|
| count | 35.000000 | 35.000000 |
| mean | 2890.228571 | 2901.800000 |
| std | 2824.305579 | 2831.802988 |
| min | 541.000000 | 541.000000 |
| 25% | 1228.000000 | 1228.000000 |
| 50% | 1757.000000 | 1763.000000 |
| 75% | 2888.500000 | 2895.000000 |
| max | 10752.000000 | 10796.000000 |
해당 연도 요약 통계#
2017년 부터 2021년까지 5년간의 자료가 있기 때문에 2017년 자료만 보고 싶은 경우, 이번 예시에서는 boolean 이용해서 데이터를 slice합니다.
food_2017 = food_dat.loc[food_dat["연도"]==2017]
food_2017
| 시도 | 연도 | 산재_음식사업장수 | 고용_음식사업장수 | |
|---|---|---|---|---|
| 0 | 광주 | 2017.0 | 796 | 801 |
| 5 | 대구 | 2017.0 | 1367 | 1375 |
| 10 | 대전 | 2017.0 | 933 | 927 |
| 15 | 부산 | 2017.0 | 1713 | 1720 |
| 20 | 서울 | 2017.0 | 6069 | 6117 |
| 25 | 울산 | 2017.0 | 541 | 541 |
| 30 | 인천 | 2017.0 | 1319 | 1318 |
여기에도 describe method를 사용해서 기초통계량을 확인합니다.
food_2017.describe()
| 연도 | 산재_음식사업장수 | 고용_음식사업장수 | |
|---|---|---|---|
| count | 7.0 | 7.000000 | 7.000000 |
| mean | 2017.0 | 1819.714286 | 1828.428571 |
| std | 0.0 | 1914.542827 | 1931.984805 |
| min | 2017.0 | 541.000000 | 541.000000 |
| 25% | 2017.0 | 864.500000 | 864.000000 |
| 50% | 2017.0 | 1319.000000 | 1318.000000 |
| 75% | 2017.0 | 1540.000000 | 1547.500000 |
| max | 2017.0 | 6069.000000 | 6117.000000 |
2017년 중에 산재 보험을 가입한 음식 사업장 수를 많은 지역구대로 정렬 해보려 합니다.
정렬하기 위해선 sort_values method 를 씁니다.
()괄호 안에는 해당 열을 지정하고, 뒤에는 따로 원하는 옵션을 넣습니다.
food_2017.sort_values(by="산재_음식사업장수", ascending=False)
| 시도 | 연도 | 산재_음식사업장수 | 고용_음식사업장수 | |
|---|---|---|---|---|
| 20 | 서울 | 2017.0 | 6069 | 6117 |
| 15 | 부산 | 2017.0 | 1713 | 1720 |
| 5 | 대구 | 2017.0 | 1367 | 1375 |
| 30 | 인천 | 2017.0 | 1319 | 1318 |
| 10 | 대전 | 2017.0 | 933 | 927 |
| 0 | 광주 | 2017.0 | 796 | 801 |
| 25 | 울산 | 2017.0 | 541 | 541 |
반대로 출동 횟수가 적은 대로 정렬 해보려면 ascending부분을 지우면 됩니다.
food_2017.sort_values(by="산재_음식사업장수")
| 시도 | 연도 | 산재_음식사업장수 | 고용_음식사업장수 | |
|---|---|---|---|---|
| 25 | 울산 | 2017.0 | 541 | 541 |
| 0 | 광주 | 2017.0 | 796 | 801 |
| 10 | 대전 | 2017.0 | 933 | 927 |
| 30 | 인천 | 2017.0 | 1319 | 1318 |
| 5 | 대구 | 2017.0 | 1367 | 1375 |
| 15 | 부산 | 2017.0 | 1713 | 1720 |
| 20 | 서울 | 2017.0 | 6069 | 6117 |
문자열 데이터인 “시도” 를 가지고 정렬해보겠습니다.
food_2017.sort_values(by="시도")
| 시도 | 연도 | 산재_음식사업장수 | 고용_음식사업장수 | |
|---|---|---|---|---|
| 0 | 광주 | 2017.0 | 796 | 801 |
| 5 | 대구 | 2017.0 | 1367 | 1375 |
| 10 | 대전 | 2017.0 | 933 | 927 |
| 15 | 부산 | 2017.0 | 1713 | 1720 |
| 20 | 서울 | 2017.0 | 6069 | 6117 |
| 25 | 울산 | 2017.0 | 541 | 541 |
| 30 | 인천 | 2017.0 | 1319 | 1318 |
“시도” 란을 보시면 가나다 순으로 정렬되는 것을 확인할 수 있습니다. 반대로 정렬하기 위해서는 ascending 함수를 사용해서 정렬할 수 있습니다.
해당 시도 통계#
이번에는 부산만 출력하겠습니다.
food_busan = food_dat.loc[food_dat["시도"]=="부산"]
food_busan
| 시도 | 연도 | 산재_음식사업장수 | 고용_음식사업장수 | |
|---|---|---|---|---|
| 15 | 부산 | 2017.0 | 1713 | 1720 |
| 16 | 부산 | 2018.0 | 2159 | 2168 |
| 17 | 부산 | 2019.0 | 3205 | 3215 |
| 18 | 부산 | 2020.0 | 3508 | 3508 |
| 19 | 부산 | 2021.0 | 3829 | 3836 |
5년간 부산의 기초통계량을 보겠습니다. 연도에 대한 기초통계는 필요 없으므로 삭제 후 진행하겠습니다.
food_busan = food_busan.drop("연도", axis = 1)
food_busan.describe()
| 산재_음식사업장수 | 고용_음식사업장수 | |
|---|---|---|
| count | 5.000000 | 5.000000 |
| mean | 2882.800000 | 2889.400000 |
| std | 905.856059 | 904.522968 |
| min | 1713.000000 | 1720.000000 |
| 25% | 2159.000000 | 2168.000000 |
| 50% | 3205.000000 | 3215.000000 |
| 75% | 3508.000000 | 3508.000000 |
| max | 3829.000000 | 3836.000000 |
5년간의 부산의 산재보험 가입한 음식 사업장 수가 많은 순으로 보려한다.
food_busan.sort_values(by="산재_음식사업장수", ascending=False)
| 시도 | 산재_음식사업장수 | 고용_음식사업장수 | |
|---|---|---|---|
| 19 | 부산 | 3829 | 3836 |
| 18 | 부산 | 3508 | 3508 |
| 17 | 부산 | 3205 | 3215 |
| 16 | 부산 | 2159 | 2168 |
| 15 | 부산 | 1713 | 1720 |
데이터 내보내기#
처음에 만든 2017년 요약데이터를 csv 내보내려면 to_csv를 입력하고 괄호() 안에는 저장링크를 넣고 마지막 부분에는 저장할 파일 이름을 지정하면 됩니다.
summary2017 = food_2017.describe()
summary2017.to_csv("2017년요약.csv", encoding = 'cp949')
엑셀 .xlsx로 내보낼수도 있습니다.
summary2017.to_excel("2017년요약.xlsx", encoding = 'cp949')
만약 시트 이름을 바꾸고 싶다면 sheet_name을 추가하자.
summary2017.to_excel("2017년요약.xlsx", encoding = 'cp949', sheet_name='Sheet_name_1')
만약 여러 개 시트에 저장하고 싶다면 다음과 같이 지정해주면 됩니다.
with pd.ExcelWriter("요약표 작업.xlsx") as writer:
summary2017.to_excel(writer, sheet_name='2017년도 요약표', encoding = 'cp949')
df_busan.to_excel(writer, sheet_name='부산 요약표', encoding = 'cp949')
저장했던 데이터를 다시 불러와보자. 특정 시트를 지정해주지 않으면 기본적으로 첫 번째 시트를 불러옵니다.
excel1 = pd.read_excel("요약표 작업.xlsx", index_col=0)
excel1
| 연도 | 산재_음식사업장수 | 고용_음식사업장수 | |
|---|---|---|---|
| count | 7 | 7.000000 | 7.000000 |
| mean | 2017 | 1819.714286 | 1828.428571 |
| std | 0 | 1914.542827 | 1931.984805 |
| min | 2017 | 541.000000 | 541.000000 |
| 25% | 2017 | 864.500000 | 864.000000 |
| 50% | 2017 | 1319.000000 | 1318.000000 |
| 75% | 2017 | 1540.000000 | 1547.500000 |
| max | 2017 | 6069.000000 | 6117.000000 |
특정 시트를 불러오고 싶다면 sheet_name로 시트명이나 시트번호를 입력합니다.
excel2 = pd.read_excel("요약표 작업.xlsx", sheet_name = '2017년도 요약표', index_col=0) # 시트명으로 불러오기.
excel2
| 연도 | 산재_음식사업장수 | 고용_음식사업장수 | |
|---|---|---|---|
| count | 7 | 7.000000 | 7.000000 |
| mean | 2017 | 1819.714286 | 1828.428571 |
| std | 0 | 1914.542827 | 1931.984805 |
| min | 2017 | 541.000000 | 541.000000 |
| 25% | 2017 | 864.500000 | 864.000000 |
| 50% | 2017 | 1319.000000 | 1318.000000 |
| 75% | 2017 | 1540.000000 | 1547.500000 |
| max | 2017 | 6069.000000 | 6117.000000 |