usecols 키워드 인자 : import할 모든 열의 이름 리스트나 열 번호 리스트를 전달
nrows 인자 : 임포트되는 행의 수 선택
skiprows 인자와 결합할 때 유용하다skiprows : 건너뛸 행 번호 list, 행 건너뛸지 결정하는 함수, 건너뛸 행의 개수를 인자로 받는다
import된 첫 번째 행을 자동으로 header(column_name)으로 만든다.
→ 컬럼 이름이 포함된 행을 건너뛴다면 header=None으로 지정해야만 한다.
열 이름이 없을 때, 이름을 할당하려면 read_csv의 다른 인자인 names를 사용한다.
names 인자 : 사용할 열 이름 리스트를 인자로 받는다.
열 개수가 적은 데이터셋의 경우, 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 방식으로 데이터가 들어오지만 복잡하게 중첩된 경우에는 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 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 : 병합의 대상 브랜치
piano를 main에 병합할 때:
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
git pull origin git pull origin dev : origin의 dev 브랜치에 pull
원격에서 pull 하기 전에 로컬 작업을 저장해둬야 한다.
원격에 push 하려면
git push remote local_branch : local_branch에서 remote로 pushgit push origin main : 로컬 main에서 origin으로 push원격에 없는 로컬 브랜치가 있다면?
git push origin local_branch_name
모듈성, 문서화, 테스트
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 패키지 공유
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 : 가독성 개선을 위한 코드 분석
column_to_label() 호출로 대체합니다.prepare_smartphone_data() 함수가 실제로 NaN을 어떻게 처리하는지(예: dropna()를 사용하는지 등) 확인하고, 테스트 코드의 assert 문이 그 로직을 정확히 검증하도록 수정합니다.pytest를 실행하여 결과가 ExitCode.OK(보통 0)를 반환하는지 확인합니다.docstring에 example 추가할 지?
변환 검증
.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 : 예기치 않은 일 - 이전에 보지 못한 데이터 타입) exerro : 데이터 타입 변경, 데이터 제공 Xjson → 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'는 새로 쓰기)