Data type - yaml, csv

6 minute read

YAML

  • 들여쓰기를 사용해 계층 구조를 표현
  • Jason 대용으로 사용되며, 애플리케이션 설정 파일을 작성할 때 많이 사용됩니다.
  • 기본은 배열, 해시, 스칼라(문자열, 숫자, 불리언)
  • 공백에 들여쓰기가 있으면 중첩 배열 표현 가능
  • 또한 플로우 스타일이 제공되어 [n1, n2, n3]로 표현할 수 있다.
!pip install pyyaml
import yaml

yaml_str = """
Date: 2017-03-10
PriceList:
    -
        item_id: 1000
        name: Banana
        color: yellow
        price: 800
    -
        item_id: 1001
        name: Orange
        color: orange
        price: 1400
    -
        item_id: 1002
        name: Apple
        color: red
        price: 2400
"""

{'Date': datetime.date(2017, 3, 10),
 'PriceList': [{'item_id': 1000,
   'name': 'Banana',
   'color': 'yellow',
   'price': 800},
  {'item_id': 1001, 'name': 'Orange', 'color': 'orange', 'price': 1400},
  {'item_id': 1002, 'name': 'Apple', 'color': 'red', 'price': 2400}]}

yaml_str = """
- Yellow
-
    - Banana
    - Orange
- Red
-
    - Apple
    - Strawberr
"""

['Yellow', ['Banana', 'Orange'], 'Red', ['Apple', 'Strawberr']]

yaml_str = """
name: Gurum
property:
    age: 4
    color: brown
"""

{'name': 'Gurum', 'property': {'age': 4, 'color': 'brown'}}

  • 배열과 해시를 조합하여 복잡한 문자열 표현
yaml_str = """
- name: Gurum
  color: brown
  age: 4
  favorites:
      - Banana
      - Orange
"""

[{'name': 'Gurum',
  'color': 'brown',
  'age': 4,
  'favorites': ['Banana', 'Orange']}]

  • 플로우 스타일
yaml_str = """
- name: Taro
  favorites: ["Banana", "Miso soup"]
- name: Mike
  favorites: ["Orange", "Candy"]
"""

[{'name': 'Taro', 'favorites': ['Banana', 'Miso soup']},
 {'name': 'Mike', 'favorites': ['Orange', 'Candy']}]

  • 여러줄 문자
yaml_str = """
multi-line: |
    I like Banana.
    I like Mango.
    I like Orange
"""

{'multi-line': 'I like Banana.\nI like Mango.\nI like Orange\n'}

  • 앵커와 별칭(Alias) 기능도 제공
yaml_str = """
# 정의
color_def:
    - &color1 "#FF0000"
    - &color2 "#00FF00"
    - &color3 "#00FFFF"

# 별칭 테스트
color:
    title: *color1
    body: *color2
    link: *color3
"""

{'color_def': ['#FF0000', '#00FF00', '#00FFFF'],
 'color': {'title': '#FF0000', 'body': '#00FF00', 'link': '#00FFFF'}}

CSV/TSV/SSV

  • CSV(comma-separated values), TSV(tab-separated values), SSV(space-separated values)
  • 첫 번째 레코드는 헤더로 사용가능합니다.
  • 각 레코드는 같은 구성을 가집니다.
  • 각 필드를 큰 따옴표로 둘러싸도 되고, 둘러싸지 않아도 됩니다.
  • 그러나 필드 내부에 큰따옴표, 쉼표, 줄바꿈이 있을 때는 반드시 큰따옴표로 둘러싸야 합니다.
  • 형식이 단순하지만 마이크로소프트 엑셀에서는 CSV 형식으로 출력할 때 한국어느 EUC-KR형식으로 출력하기 때문에 인코딩이 꼬일 수 있으므로 주의해야 합니다.

import codecs

# EUC-KR로 저장된 CSV파일 읽기
filename = "list-euckr.csv"
csv = codecs.open(filename, "r", "euc_kr").read()

# 엑셀 최신 버전에는 "CSV UTF-8"이 따로 있습니다. 하지만 국내 기업에서 제공하는 CSV 파일은 대부분 EUC-KR입니다..
# 따라서 우선은 저장할 때 그냥 CSV형식으로 저장해 주세요(자동으로 EUC_KR로 저장)
csv

'ID,이름,가격\r\n1000,비누,300\r\n1001,장갑,150\r\n1002,마스크,230\r\n'

# CSV을 파이썬 리스트로 변환하기
data = []
rows = csv.split("\r\n")
for row in rows:
    if row == "": continue
    cells = row.split(",") # string to list
    data.append(cells)

# \r = CR (Carriage Return) → Used as a new line character in Mac OS before X
# \n = LF (Line Feed) → Used as a new line character in Unix/Mac OS X
# \r\n = CR + LF → Used as a new line character in Windows
data

[['ID', '이름', '가격'],
 ['1000', '비누', '300'],
 ['1001', '장갑', '150'],
 ['1002', '마스크', '230']]

  • 대부분의 CSV파일은 이전과 같이 분석할 수 있다. 그러나 데이터가 큰 따옴표로 둘러싸인 경우 분석하기 어려워진다. 그래서 CSV 형식을 분석하기 위한 csv모듈을 사용합니다.
import csv, codecs

filename = 'list-euck.csv'
fp = codecs.open(filename, "r", encoding = "euc_kr")

reader = csv.reader(fp, delimiter=",", quotechar='"')
for cells in reader:
  print(cells[1], cells[2])

reader
<_csv.reader at 0x2263aa35c78>
  • reader는 스트링 형식의 문자열이 아니라 csv position을 지정하는 포인터 역할을 한다. 그래서 한 줄 씩 읽어야 표시가 된다.

  • python에서 csv파일 쓰기
  • read와 동일 하고, 한 줄 씩 쓸때는 writerow()함수를 이용합니다.
import csv, codecs

with codecs.open("test.csv", "w", "euc_kr") as fp:
    writer = csv.writer(fp, delimiter=",", quotechar='"')
    writer.writerow(["ID", "이름", "가격"])
    writer.writerow(["1000", "SD 카드", 30000])
    writer.writerow(["1001", "키보드", 21000])

엑셀 파일 분석(with Pandas)

시도별 인구 변동 현황 [단위 : 천명]									
	2009	2010	2011	2012	2013	2014	2015	2016	2017
계	49,773	50,515	50,734	50,948	51,141	51,328	51,529	51,696	51,778
서울	10,208	10,312	10,250	10,195	10,144	10,103	10,022	9,930	9,857
부산	3,543	3,568	3,551	3,538	3,528	3,519	3,513	3,498	3,470
대구	2,489	2,512	2,508	2,506	2,502	2,493	2,487	2,484	2,475
인천	2,710	2,758	2,801	2,844	2,880	2,903	2,925	2,943	2,948
광주	1,433	1,455	1,463	1,469	1,473	1,476	1,472	1,469	1,463
대전	1,484	1,504	1,516	1,525	1,533	1,532	1,518	1,514	1,502
울산	1,114	1,126	1,136	1,147	1,156	1,166	1,173	1,172	1,165
세종	-	-	-	113	122	156	210	243	280
경기	11,460	11,787	11,937	12,093	12,235	12,358	12,522	12,716	12,873
강원	1,512	1,530	1,536	1,539	1,542	1,544	1,549	1,550	1,550
충북	1,527	1,549	1,563	1,566	1,573	1,579	1,583	1,591	1,594
충남	2,037	2,075	2,101	2,029	2,048	2,062	2,077	2,096	2,116
전북	1,854	1,869	1,874	1,873	1,873	1,872	1,869	1,864	1,854
전남	1,913	1,918	1,914	1,910	1,907	1,906	1,908	1,903	1,896
경북	2,669	2,690	2,699	2,698	2,699	2,701	2,702	2,700	2,691
경남	3,250	3,291	3,309	3,319	3,333	3,350	3,364	3,373	3,380
제주	562	571	576	584	593	607	624	641	657

!pip install openpyxl

import openpyxl

# 엑셀 파일 열기
filename = "stats_104102.xlsx"
book = openpyxl.load_workbook(filename)

# 맨 앞의 시트 추출하기
sheet = book.worksheets[0]

# 시트의 각 행을 순서대로 추출하기
data = []
for row in sheet.rows:
    data.append([
        row[0].value,
        row[9].value
    ])

# 필요없는 줄 제거하기
del data[0]
del data[1]
del data[2]    

# 데이터를 인구 순서로 정렬합니다.

data = sorted(data, key = lambda x: x[1], reverse = True)

# 하위 5위를 출력
for i, a in enumerate(data):
    if (i >= 5): break
    print(i+1, a[0], int(a[1]))

1 경기 12873
2 서울 9857
3 경남 3380
4 인천 2948
5 경북 2691

  • 엑셀에 파일 쓰기
import openpyxl

filename = '../stats_104102.xlsx'
book = openpyxl.load_workbook(filename)

# 활성화된 시트 추출하기
sheet = book.active

# 서울을 제외한 인구를 구해서 쓰기
for i in range(0, 9):
    total = int(sheet[str(chr(i + 66)) + "3"].value)
    seoul = int(sheet[str(chr(i + 66)) + "4"].value)
    output = total - seoul
    print("서울 제외 인구 = ", output)
    # 쓰기
    sheet[str(chr(i+66) + "21")] = output
    cell = sheet[str(chr(i+66) + "21")]
    # 폰트와 색상 변경해보기
    cell.font = openpyxl.styles.Font(size=14, color="FF0000")
    cell.number_format = cell.number_format

# 엑셀 파일 저장하기
filename = "population.xlsx"
book.save(filename)
print("ok")
시도별 인구 변동 현황 [단위 : 천명]									
	2009	2010	2011	2012	2013	2014	2015	2016	2017
계	49,773	50,515	50,734	50,948	51,141	51,328	51,529	51,696	51,778
서울	10,208	10,312	10,250	10,195	10,144	10,103	10,022	9,930	9,857
부산	3,543	3,568	3,551	3,538	3,528	3,519	3,513	3,498	3,470
대구	2,489	2,512	2,508	2,506	2,502	2,493	2,487	2,484	2,475
인천	2,710	2,758	2,801	2,844	2,880	2,903	2,925	2,943	2,948
광주	1,433	1,455	1,463	1,469	1,473	1,476	1,472	1,469	1,463
대전	1,484	1,504	1,516	1,525	1,533	1,532	1,518	1,514	1,502
울산	1,114	1,126	1,136	1,147	1,156	1,166	1,173	1,172	1,165
세종	-	-	-	113	122	156	210	243	280
경기	11,460	11,787	11,937	12,093	12,235	12,358	12,522	12,716	12,873
강원	1,512	1,530	1,536	1,539	1,542	1,544	1,549	1,550	1,550
충북	1,527	1,549	1,563	1,566	1,573	1,579	1,583	1,591	1,594
충남	2,037	2,075	2,101	2,029	2,048	2,062	2,077	2,096	2,116
전북	1,854	1,869	1,874	1,873	1,873	1,872	1,869	1,864	1,854
전남	1,913	1,918	1,914	1,910	1,907	1,906	1,908	1,903	1,896
경북	2,669	2,690	2,699	2,698	2,699	2,701	2,702	2,700	2,691
경남	3,250	3,291	3,309	3,319	3,333	3,350	3,364	3,373	3,380
제주	562	571	576	584	593	607	624	641	657
	39565	40203	40484	40753	40997	41225	41507	41766	41921


  • Pandas로 엑셀 파일 읽고 쓰기
!pip install pandas
!pip install xlrd

import pandas as pd

filename = "../stats_104102.xlsx"
sheet_name = "stats_104102"
book = pd.read_excel(filename, sheetname = sheet_name, header = 1)

# 2015년 인구로 정렬
book = book.sort_values(by=2017, ascending = False)
print(book)
2009   2010   2011   2012   2013   2014   2015   2016   2017
계   49773  50515  50734  50948  51141  51328  51529  51696  51778
경기  11460  11787  11937  12093  12235  12358  12522  12716  12873
서울  10208  10312  10250  10195  10144  10103  10022   9930   9857
부산   3543   3568   3551   3538   3528   3519   3513   3498   3470
경남   3250   3291   3309   3319   3333   3350   3364   3373   3380
인천   2710   2758   2801   2844   2880   2903   2925   2943   2948
경북   2669   2690   2699   2698   2699   2701   2702   2700   2691
대구   2489   2512   2508   2506   2502   2493   2487   2484   2475
충남   2037   2075   2101   2029   2048   2062   2077   2096   2116
전남   1913   1918   1914   1910   1907   1906   1908   1903   1896
전북   1854   1869   1874   1873   1873   1872   1869   1864   1854
충북   1527   1549   1563   1566   1573   1579   1583   1591   1594
강원   1512   1530   1536   1539   1542   1544   1549   1550   1550
대전   1484   1504   1516   1525   1533   1532   1518   1514   1502
광주   1433   1455   1463   1469   1473   1476   1472   1469   1463
울산   1114   1126   1136   1147   1156   1166   1173   1172   1165
제주    562    571    576    584    593    607    624    641    657
세종      -      -      -    113    122    156    210    243    280

Categories:

Updated:

Leave a comment