2026.4.10(Fri)

오유찬·2026년 4월 10일

DE

목록 보기
6/16

Streamlined Data Ingestion with pandas

usecols 키워드 인자 : import할 모든 열의 이름 리스트나 열 번호 리스트를 전달

  • 함수를 전달해 열 선택 가능

nrows 인자 : 임포트되는 행의 수 선택

  • 파일을 chunks 단위로 처리하기 위해 skiprows 인자와 결합할 때 유용하다

skiprows : 건너뛸 행 번호 list, 행 건너뛸지 결정하는 함수, 건너뛸 행의 개수를 인자로 받는다

import된 첫 번째 행을 자동으로 header(column_name)으로 만든다.
→ 컬럼 이름이 포함된 행을 건너뛴다면 header=None으로 지정해야만 한다.

열 이름이 없을 때, 이름을 할당하려면 read_csv의 다른 인자인 names를 사용한다.
names 인자 : 사용할 열 이름 리스트를 인자로 받는다.

  • 데이터의 모든 열에 대한 이름이 포함되어야 한다.
  • 일부 이름을 바꾸고 싶으면 import 작업이 끝난 후 진행

열 개수가 적은 데이터셋의 경우, Data Dictionary를 참고해 직접 리스트를 만들 수도 있다.

오류 및 결측치 처리

  • 데이터 타입 지정 실수 (zipcode를 문자열이 아니라 정수로 pandas가 판단하는 문제)
    read_csv의 키워드 인자인 dtype으로 열의 데이터 타입을 지정할 수 있다. - dictionary 형태

  • 결측치 + 결측치라 판단해야 하는 값 (zipcode = 0인 경우)
    na_values 키워드 인자 → 단일 값, 값들의 리스트, 컬럼-결측치 값으로 구성된 딕셔너리를 전달할 수 있다.

오류가 있는 행

  • on_bad_lines
  • error_bad_lines : 실행 X + 에러문
  • warn_bad_lines : 실행 O + 경고

pd.concat 함수는 여러 개의 pandas 객체(DataFrame이나 Series 등)를 하나로 합칠 때 사용하는 함수입니다. 이 함수의 첫 번째 인자는 반드시 DataFrame들의 리스트(또는 다른 iterable)여야 합니다.

boolean 값 설정
true_values=['Yes'], false_values=['No'] 인자
→ NA가 True로 변환되는 문제는 여전하다.

+) dtype=bool보다는 dtype=boolean을 사용하면 True, False, NA를 모두 유지할 수 있어 데이터 품질 관리에 유리하다.

JSON

  • record orientation : 레코드 방식의 JSON은 딕셔너리들의 리스트로 구성된다. 각 dictionary는 테이블의 한 행이 된다.
  • column orientation : key-column name, value - 해당 컬럼의 데이터 리스트나 행 인덱스가 포함된 딕셔너리

실무에서는 Record 방식으로 데이터가 들어오지만 복잡하게 중첩된 경우에는 json_normalize라는 tool을 사용한다.

requests.get()의 결과값은 데이터와 메타데이터를 포함하는 response 객체이다.
여기서 실제 데이터만 뽑아내려면 .json() 메서드를 사용해야 하는데, 중요한 점은 .json() 메서드가 dictionary를 반환한다는 것이다. pd.read_json()은 문자열을 기대하기 때문에 dictionary를 직접 분석할 수 없다. → pd.DataFrmae()을 사용한다.

pd.json_normalize : dictinoary나 dictionary의 list를 받아 데이터프레임으로 반환한다.
중첩된 속성의 열 이름은 속성.하위속성을 따르지만 . 구분자는 판다스의 열 선택 문법과 충돌할 수도 있기 때문에, sep인자를 사용해 다른 구분자로 지정하는 것이 좋다.

df = json_normalize(data['job'], sep='_')

{
    "store_name": "Cafe Gemini",
    "location": "Seoul",
    "reviews": [
        {"user": "Alice", "score": 5},
        {"user": "Bob", "score": 4}
    ]
}

record_path : reviews 컬럼을 2개의 행으로 쪼개준다.
없으면 reviews 컬럼 하나에 리스트가 통째로 들어간다.

record_path는 보통 meta 인자와 함께 사용한다.
reviews의 리스트를 펼치게 되면 {"user": "Alice", "score": 5}에 해당하는 상위 수준의 정보(가게이름, 위치)가 사라지기 때문에 meta를 이용해 그 정보를 다시 붙여줘야 한다.

다른 상위 정보의 하위 정보를 붙이려고 할 때는 리스트를 활용한다.

flat_cafes = json_normalize(data["businesses"],
	sep="_",
	record_path="categories",
		meta=['name',
		'alias',
		'rating',
		['coordinates', 'latitude'],
		['coordinates', 'longitude']],
		meta_prefix="biz_")

['coordinates', 'latitude'] : coordinates 안에 있는 latitude의 정보

cafes = pd.concat([top_50_cafes, next_50_cafes], ignore_index=True)

  • pd.concat은 DataFrame의 리스트를 인자로 전달해야 한다.

#Git

git branch new_name : 브랜치 생성
git switch -c new_branch : branch 생성 후 해당 branch로 이동![[스크린샷 2026-04-10 오후 4.48.40.png]]

git branch -m old_name new_name : branch 이름 변경
git branch -d delete_branch_name : branch 삭제
병합되지 않은 채면 오류가 뜨는데, -D 플래그 ㅅ용하면 삭제 가능하다.

병합

source : 병합의 원본 브랜치
destination : 병합의 대상 브랜치

pianomain에 병합할 때:

  • piano - source
  • main -destination

destination 브랜치에 이동한 후에 git merge 병합시킬_브랜치
자기가 사용 중인 브랜치를 다른 브랜치에 병합시키려면 git merge using_branch destination

게시판 기능을 만들기 위해 borad 브랜치를 만들고 병합했는데 에러가 생겼어
그러면 board 브랜치에서 고치는 게 아니라 board는 삭제하고 board_fix 브랜치를 만들고 작업 후에 다시 병합한다.

병합 충돌

서로 다른 두 파일을 병합하면 git이 어느 걸 병합해야 할 지 알 수 없다. → 충돌!

원격의 파일을 로컬 저장소와 동기화하려면 원격에서 브랜치를 가져와야 한다.
이를 위해서 원격 이름을 지정해 git fetch를 사용한다.
git fetch origin

  • 원격의 모든 브랜치가 로컬 저장소에 내려온다.
  • 브랜치가 원격에만 존재했다면, 로컬에도 생성된다.
  • 원격의 내용을 로컬에 병합하지는 않음에 주의해라.

git fetch origin main
origin 원격 저장소 중 특정 브랜치만 가지고 오고 싶을 때는 브랜치도 같이 선언해라.

브랜치를 가지고 왔으면 저장소 간 내용을 동기화해야 한다.
git merge origin

  • local branch를 명시하지 않으면 현재 위치한 브랜치에 병합된다.
    git pull origin

git pull origin dev : origin의 dev 브랜치에 pull

원격에서 pull 하기 전에 로컬 작업을 저장해둬야 한다.

git push

원격에 push 하려면

  • 먼저 로컬에 변경 사항 저장
  • git push remote local_branch : local_branch에서 remote로 push
  • git push origin main : 로컬 main에서 origin으로 push

원격에 없는 로컬 브랜치가 있다면?
git push origin local_branch_name


Python으로 배우는 software engineering principle

모듈성, 문서화, 테스트

PyPi : python package index

package 이름은 소문자로 설정

__init__.py 가 있어야 python이 우리가 만든 패키지를 인식한다.

utils.py - 서브 모듈로 불리며
pakcage_name.sub_module_name.function_name 형식으로 호출할 수 있다.

또 다른 방법으로는,

# my_package/__init__.py
form .utils import we_need_to_talk

을 설정해두면, 다른 work directory에서 작업할 때

import my_package

만 해도 import 할 수 있다. init 파일에서 import를 대신 해주기 때문.
핵심 기능을 __init__.py에서 임포트하여 바로 접근할 수 있도록 해주고 비주류 함수는 서브모듈 점 표기법으로 접근토록 한다.

package 내부 package도 설정할 수 있는데, 방법은 똑같다.

python 패키지 공유

  • setup.py : package를 어떻게 설치할 지
  • requirements.txt : 필요한 환경 재현하는 방법
    pip install -r requirements.txt

setup.py 설정되면 터미널에서 같은 디렉토리 내 터미널에서 pip install . → 패키지 설치 된다.

DRY 원치
Don't Repeart Yourself : 반복할만한 코드 재작성하지 마라.
상속

from .parent_class import ParentClass

class ChildClass(ParentClass):
	def __init__(self):
		ParentClass.__init__(self)
		# Add child's unique thiing

다중 상속 개념도 알아둘 것!

주석은 코드가 무엇을 하는지가 아니래 왜 코드를 그렇게 작성헀는지 써라

test
doctest & pytest
docstring → doctest

객체 2개를 비교할 때는 ==로 하기보다는 속성을 비교하는 방식으로 검증한다.

test.py를 작성할 때는 소스코드 제목은 시작이나 끝이 test 이어야 하고,
함수 정의할 때는 test가 앞에 붙어야 하며, assert로 검증해줘야 한다.

Sphinx로 docstring을 문서화할 수 있다.

ivar 키워드 : 인스턴스 변수

  • 변수라고 하지 않고 ivar라고 하는 이유 : 선언되는 위치에 따라 이름이 달라지기 때문에
def __init__(self, table_name):
	# 여기서 self.table_name이 ivar 변수다.
	self.table_name = table.name

Travix CI
새 코드를 추가할 때, Travis가 자동으로 테스트 실행하고, 변경으로 문제가 생기면 알려준다.
수정한 걸 push 하면 다시 테스트를 실행해 수정이 제대로 됐는지 확인해준다.
빌드 예약도 가능

Codecov : 자동 테스트가 코드의 어떤 부분을 검증하고 있는지 살펴볼 수 있게 해주는 도구

  • 테스트 커버리지라고 한다.

Code Climate : 가독성 개선을 위한 코드 분석


Performing a Code Review

  • 리팩토링 (DRY 원칙 적용): 시각화 함수 내에서 중복되는 라벨 생성 로직을 column_to_label() 호출로 대체합니다.
  • 유닛 테스트 수정: prepare_smartphone_data() 함수가 실제로 NaN을 어떻게 처리하는지(예: dropna()를 사용하는지 등) 확인하고, 테스트 코드의 assert 문이 그 로직을 정확히 검증하도록 수정합니다.
  • 최종 검증: pytest를 실행하여 결과가 ExitCode.OK(보통 0)를 반환하는지 확인합니다.

docstring에 example 추가할 지?


Python으로 ETL과 ELT

변환 검증

  • .nsmallest(10, ['timestamps'] : 지정한 열 목록에서 가장 작은 값 10개
  • .nlargest(10, ['timestamps']

to_csv 했을 때 저장 제대로 되었는지 확인하려면

import os
print(os.path.exists('example.csv'))

log : 파이프라인이 실행되는 동안 생성되어 기록되는 메세지

  • 실패 시 성능 기록
  • 실패 시 원인 파악 출발점 제공

logging - 6가지
debug, info, warning, error

  • debug : 파이프라인 만드는 동안 사용 → 차원, 타입, 변수 값 제공
  • info : 파이프라인 실행 전반에 걸쳐 기본 정보와 체크포인트 제공
  • warning : 예기치 않은 일 - 이전에 보지 못한 데이터 타입) ex
  • erro : 데이터 타입 변경, 데이터 제공 X

json → dictionary → DataFrame

isinstance(pipeline, data_type) : 객체와 해당 타입 일치하면 True

@pytest.fixture() : test data와 객체를 여러 테스트에서 공유할 수 있게 해주는 함수

logging.basicConfig는 파이썬의 표준 라이브러리인 logging 모듈에서 로그 시스템의 가장 기본적인 설정을 한 번에 마치는 함수

  • level: 어떤 수준의 로그부터 출력할지 결정합니다. (DEBUG < INFO < WARNING < ERROR < CRITICAL)
  • format: 로그가 출력될 모양을 지정합니다. (시간, 로그 레벨, 메시지 등)
  • filename: 로그를 콘솔이 아닌 파일에 저장하고 싶을 때 파일 경로를 지정합니다.
  • filemode: 파일을 열 때의 모드입니다. ('a'는 이어쓰기, 'w'는 새로 쓰기)
profile
열심히 하면 재밌다

0개의 댓글