JSON과 CSV
En Python, JSON과 CSV 데이터를 다루는 방법, aprendamos. 이 두 가지는 가장 널리 사용되는 데이터 교환 형식입니다.
JSON 다루기 📦
JSON(JavaScript Object Notation)은 데이터를 저장하고 전송하는 경량 형식입니다.
기본 사용법
import json
# Python 객체 → JSON 문자열
data = {
'name': '홍길동',
'age': 30,
'city': '서울',
'hobbies': ['독서', '등산', '요리']
}
json_string = json.dumps(data)
print(json_string)
# {"name": "홍길동", "age": 30, "city": "서울", "hobbies": ["독서", "등산", "요리"]}
# JSON 문자열 → Python 객체
parsed_data = json.loads(json_string)
print(parsed_data['name']) # 홍길동
파일로 저장하고 읽기
import json
# JSON 파일로 저장
data = {
'users': [
{'id': 1, 'name': '김철수', 'email': 'kim@example.com'},
{'id': 2, 'name': '이영희', 'email': 'lee@example.com'},
]
}
with open('users.json', 'w', encoding='utf-8') as f:
json.dump(data, f, ensure_ascii=False, indent=2)
# JSON Lectura de Archivos
with open('users.json', 'r', encoding='utf-8') as f:
loaded_data = json.load(f)
print(loaded_data)
JSON 포맷팅 옵션
import json
data = {'name': '홍길동', 'age': 30, 'skills': ['Python', 'JavaScript']}
# 들여쓰기 없음 (압축)
compact = json.dumps(data)
print(compact)
# {"name": "홍길동", "age": 30, "skills": ["Python", "JavaScript"]}
# 들여쓰기 2칸 (읽기 쉽게)
pretty = json.dumps(data, indent=2, ensure_ascii=False)
print(pretty)
# {
# "name": "홍길동",
# "age": 30,
# "skills": [
# "Python",
# "JavaScript"
# ]
# }
# 키 정렬
sorted_json = json.dumps(data, sort_keys=True, indent=2, ensure_ascii=False)
print(sorted_json)
복잡한 데이터 타입 처리
import json
from datetime import datetime
from decimal import Decimal
class DateTimeEncoder(json.JSONEncoder):
"""datetime을 JSON으로 직렬화"""
def default(self, obj):
if isinstance(obj, datetime):
return obj.isoformat()
if isinstance(obj, Decimal):
return float(obj)
return super().default(obj)
# 사용 예제
data = {
'timestamp': datetime.now(),
'amount': Decimal('123.45')
}
json_string = json.dumps(data, cls=DateTimeEncoder, indent=2)
print(json_string)
CSV 다루기 📊
CSV(Comma-Separated Values)는 표 형식 데이터를 저장하 는 간단한 형식입니다.
기본 CSV 쓰기
import csv
# CSV Escritura de Archivos
data = [
['이름', '나이', '도시'],
['홍길동', 30, '서울'],
['김철수', 25, '부산'],
['이영희', 28, '대구']
]
with open('users.csv', 'w', newline='', encoding='utf-8') as f:
writer = csv.writer(f)
writer.writerows(data)
CSV 읽기
import csv
# CSV Lectura de Archivos
with open('users.csv', 'r', encoding='utf-8') as f:
reader = csv.reader(f)
for row in reader:
print(row)
# ['이름', '나이', '도시']
# ['홍길동', '30', '서울']
# ...
DictReader: 딕셔너리로 읽기
import csv
# 헤더를 키로 사용하여 읽기
with open('users.csv', 'r', encoding='utf-8') as f:
reader = csv.DictReader(f)
for row in reader:
print(f"{row['이름']}은 {row['나이']}세이고 {row['도시']}에 삽니다.")
# 홍길동은 30세이고 서울에 삽니다.
# 김철수는 25세이고 부산에 삽니다.
DictWriter: 딕셔너리로 쓰기
import csv
# 딕셔너리 데이터를 CSV로 저장
users = [
{'name': '홍길동', 'age': 30, 'city': '서울'},
{'name': '김철수', 'age': 25, 'city': '부산'},
{'name': '이영희', 'age': 28, 'city': '대구'}
]
with open('users_dict.csv', 'w', newline='', encoding='utf-8') as f:
fieldnames = ['name', 'age', 'city']
writer = csv.DictWriter(f, fieldnames=fieldnames)
writer.writeheader() # 헤더 쓰기
writer.writerows(users) # 모든 행 쓰기
CSV 옵션
import csv
# 구분자 변경 (탭, 세미콜론 등)
with open('data.tsv', 'w', newline='', encoding='utf-8') as f:
writer = csv.writer(f, delimiter='\t')
writer.writerow(['이름', '나이'])
writer.writerow(['홍길동', 30])
# 인용 스타일
with open('quoted.csv', 'w', newline='', encoding='utf-8') as f:
# QUOTE_ALL: 모든 필드를 인용
writer = csv.writer(f, quoting=csv.QUOTE_ALL)
writer.writerow(['이름', '나이'])
# QUOTE_MINIMAL: 필요한 경우만 인용 (기본값)
writer = csv.writer(f, quoting=csv.QUOTE_MINIMAL)
writer.writerow(['홍길동', 30])
Ejemplos Prácticos 💡
예제 1: API 응답 파싱
import json
import urllib.request
def fetch_and_parse_json(url):
"""JSON API 호출 및 파싱"""
try:
with urllib.request.urlopen(url) as response:
data = response.read()
return json.loads(data)
except Exception as e:
print(f'에러 발생: {e}')
return None
# 사용 예제 (실제 API 사용)
# url = 'https://api.example.com/users'
# users = fetch_and_parse_json(url)
# 로컬 JSON Lectura de Archivos 예제
def load_user_data(filename):
"""사용자 데이터 로드"""
try:
with open(filename, 'r', encoding='utf-8') as f:
return json.load(f)
except FileNotFoundError:
print(f'파일을 찾을 수 없습니다: {filename}')
return []
except json.JSONDecodeError as e:
print(f'JSON 파싱 에러: {e}')
return []
# users = load_user_data('users.json')
# for user in users:
# print(f"{user['name']}: {user['email']}")
예제 2: 설정 파일 관리
import json
from pathlib import Path
class Config:
"""JSON 설정 파일 관리자"""
def __init__(self, config_file='config.json'):
self.config_file = Path(config_file)
self.data = self.load()
def load(self):
"""설정 파일 로드"""
if self.config_file.exists():
with open(self.config_file, 'r', encoding='utf-8') as f:
return json.load(f)
return self.get_default()
def save(self):
"""설정 파일 저장"""
with open(self.config_file, 'w', encoding='utf-8') as f:
json.dump(self.data, f, indent=2, ensure_ascii=False)
def get(self, key, default=None):
"""설정 값 가져오기"""
return self.data.get(key, default)
def set(self, key, value):
"""설정 값 설정하기"""
self.data[key] = value
self.save()
def get_default(self):
"""기본 설정"""
return {
'app_name': 'MyApp',
'version': '1.0.0',
'debug': False,
'max_connections': 100
}
# 사용 예제
config = Config()
print(f"앱 이름: {config.get('app_name')}")
config.set('debug', True)
print(f"디버그 모드: {config.get('debug')}")
예제 3: CSV에서 JSON으로 변환
import csv
import json
def csv_to_json(csv_file, json_file):
"""CSV 파일을 JSON으로 변환"""
data = []
with open(csv_file, 'r', encoding='utf-8') as f:
reader = csv.DictReader(f)
for row in reader:
# 숫자 타입 변환
for key, value in row.items():
if value.isdigit():
row[key] = int(value)
elif value.replace('.', '', 1).isdigit():
row[key] = float(value)
data.append(row)
with open(json_file, 'w', encoding='utf-8') as f:
json.dump(data, f, indent=2, ensure_ascii=False)
print(f'{csv_file} → {json_file} 변환 완료')
return data
# 사용 예제
# data = csv_to_json('users.csv', 'users.json')
예제 4: JSON에서 CSV로 변환
import json
import csv
def json_to_csv(json_file, csv_file):
"""JSON 파일을 CSV로 변환"""
with open(json_file, 'r', encoding='utf-8') as f:
data = json.load(f)
if not data:
print('데이터가 비어있습니다')
return
# 첫 번째 항목에서 키 추출
if isinstance(data, list):
fieldnames = list(data[0].keys())
else:
# 단일 객체인 경우
data = [data]
fieldnames = list(data[0].keys())
with open(csv_file, 'w', newline='', encoding='utf-8') as f:
writer = csv.DictWriter(f, fieldnames=fieldnames)
writer.writeheader()
writer.writerows(data)
print(f'{json_file} → {csv_file} 변환 완료')
# 사용 예제
# json_to_csv('users.json', 'users_output.csv')
예제 5: 엑셀 데이터 처리 (CSV 사용)
import csv
from collections import defaultdict
class SalesAnalyzer:
"""판매 데이터 분석기"""
def __init__(self, csv_file):
self.data = self.load_data(csv_file)
def load_data(self, csv_file):
"""CSV 데이터 로드"""
data = []
with open(csv_file, 'r', encoding='utf-8') as f:
reader = csv.DictReader(f)
for row in reader:
# 숫자 변환
row['amount'] = float(row['amount'])
row['quantity'] = int(row['quantity'])
data.append(row)
return data
def total_sales(self):
"""총 매출"""
return sum(item['amount'] for item in self.data)
def sales_by_product(self):
"""제품별 매출"""
sales = defaultdict(float)
for item in self.data:
sales[item['product']] += item['amount']
return dict(sales)
def top_products(self, n=5):
"""상위 N개 제품"""
sales = self.sales_by_product()
sorted_products = sorted(sales.items(), key=lambda x: x[1], reverse=True)
return sorted_products[:n]
def generate_report(self, output_file):
"""리포트 생성"""
report = {
'total_sales': self.total_sales(),
'product_count': len(self.sales_by_product()),
'top_products': [
{'product': name, 'sales': amount}
for name, amount in self.top_products()
]
}
with open(output_file, 'w', encoding='utf-8') as f:
json.dump(report, f, indent=2, ensure_ascii=False)
return report
# 사용 예제 (CSV 파일 생성)
sample_data = [
['product', 'quantity', 'amount'],
['노트북', 5, 5000000],
['마우스', 20, 500000],
['키보드', 15, 1500000],
['노트북', 3, 3000000],
]
with open('sales.csv', 'w', newline='', encoding='utf-8') as f:
writer = csv.writer(f)
writer.writerows(sample_data)
# analyzer = SalesAnalyzer('sales.csv')
# print(f'총 매출: {analyzer.total_sales():,}원')
# print(f'제품별 매출: {analyzer.sales_by_product()}')
# analyzer.generate_report('sales_report.json')