컬렉션 처리 - map, filter
map()
- 연속된 데이터(컬렉션 계열 중 리스트, 튜플 등)의 멤버를 하나씩 꺼내서 작업 진행
- ex) 모든 멤버의 값 두배 처리 : 전처리
datas = [1,2,3,4,5]
# 요구사항 : datas의 모든 멤버들의 값을 두배로 업그레이드 하시오.
# [1,2,3,4,5] -> [2,4,6,8,10]
datas * 2 # 리스트가 2번 복사된다
결과값 : [1, 2, 3, 4, 5, 1, 2, 3, 4, 5]
----------------------------------------------------------
# map()을 이용하여 멤버를 하나씩 꺼내서 두배로 업그레이드하여 다시 리스트에 담는다
# pandas 가면 apply()
%%time
def 더블함수 (x) : # 반드시 멤버를 받을 매개변수가 1개 있어야함
return x * 2 # 반드시 값을 반환해야함 -> 이러한 조건을 만족할 때 map에서 콜백함수로 작동함
# map()만 있으면 이상하게 찍힘, list로 변환해서 받아줘야함.
# 원본은 바뀌지 않음
doubled = list(map(더블함수, datas))
doubled
결과값 : [2, 4, 6, 8, 10]
- 람다함수
- 가장 빠른 함수 (고속 함수)
- 코드에 함수가 한몸처럼 적용되어 하나의 코드처럼 작동
- 1회성
- 이름이 없어서 재사용이 되지 않음
- 콜백함수 역할에서 자주 사용됨
- 함수의 인자로 함수가 적용되는 형태
lambda 매개변수1, 매개변수2, ...: 수행문(반환되는 값을 연산하는 과정, 1개만 유효)
# 람다함수 적용
%%time
list(map(lambda x: x*2, datas)), datas
결과값 : ([2, 4, 6, 8, 10], [1, 2, 3, 4, 5])
--------------------------------------------------------
# 실습 -> 리스트 컴프리헨션으로 구현
# 컴프리헨션 : 결과중심
# 속도가 제일 빠름
# 결정적 차이는 함수의 호출 여부임
%%time
[x*2 for x in datas], datas
결과값 : ([2, 4, 6, 8, 10], [1, 2, 3, 4, 5])
filter
- 필터링 용도 : 데이터에서 필요한 것만 추출 -> 조건문이 내부적으로 사용됨 -> 콜백함수의 반환값은 불린형임
# datas에서 짝수 데이터만 추출하여 리스트로 반환하시오
def 짝수필터링 (x) :
if x % 2 == 0 :
return True
return False
def 짝수필터링2 (x) :
return not x % 2
list(filter(짝수필터링, datas))
list(filter(짝수필터링2, datas))
------------------------------------------------------------
# 람다함수
list(filter(lambda x : not x%2, datas))
------------------------------------------------------------
# 리스트 컴프리헨션
[x for x in datas if not x%2]
일괄 결과값 : [2, 4]
ord
- 알파벳 문자에 대한 아스키코드값 반환
ord('A'), ord('Z'), ord('a'), ord('z')
결과값 : (65, 90, 97, 122)
# 'a'의 위치를 0으로 가정하면
# 'z'의 위치는 얼마나 떨어져 있는가?
ord('z') - ord('a')
결과값 : 25
- 정규식을 이용하여 데이터 정제(clean) 처리 수행
# 주어진 텍스트에서 알파벳 문자의 빈도를 계산하여 리스트에 담으시오
# 원 데이터에는 알파벳 이외의 문자들도 상당 수 존재함 : 노이즈 -> 노이즈 제거 후 알파벳 빈도 계산해야함
# 이렇게 패턴이 복잡해지면 정규식을 떠올려야 한다
raw_data = '''
The dog (Canis familiaris or Canis lupus familiaris) is a domesticated descendant of wolves. Also called the domestic dog, it was selectively bred during the Late Pleistocene by hunter-gatherers. Dogs and the modern gray wolf share a common ancestor.[4] Dogs were the first species to be domesticated over 14,000 years ago, before the development of agriculture, though genetic studies suggest the domestication process may have begun over 25,000 years ago. Due to their long association with humans, dogs have gained the ability to thrive on a starch-rich diet that would be inadequate for other canids.
Dogs have been bred for desired behaviors, sensory capabilities, and physical attributes. Dog breeds vary widely in shape, size, and color. They have the same number of bones (with the exception of the tail), powerful jaws that house around 42 teeth, and well-developed senses of smell, hearing, and sight. Compared to humans, dogs possess a superior sense of smell and hearing, but inferior visual acuity. Dogs perform many roles for humans, such as hunting, herding, pulling loads, protection, companionship, therapy, aiding disabled people, and assisting police and the military.
'''
# 1. 정규식을 위한 패키지 가져오기
import re
# 2. re.compile()을 이용하여 패턴 정의 -> 노이즈 제거 == 알파벳만 추출
# 알파벳 패턴 정의
'''
- [] : 문자 클래스, 문자를 표현(1개)
- a-z : 소문자 전체
- A-Z : 대문자 전체
- * : 0~무한대 반복등장 (나올 수도 있고 안 나올 수도 있고)
- + : 1~무한대 반복등장 (한 번은 반드시 등장)
- 제거 대상 : 숫자, 특수문자, 한글 등 알파벳이 아닌 다른 언어, 화이트스페이스(줄바꿈, 탭 등 이스케이프 문자), ...
-> 너무 이것저것 많음 -> 알파벳을 정의하고 나머지 모든 문자를 제거하면 됨
- ^ : []내부에서 사용하면 '해당 문자들을 제외하고'라는 의미가 됨
[]외부에서 사용하면 '시작문자'라는 의미가 됨
'''
pattern = re.compile("[^a-zA-Z]*") # 알파벳을 제외한 나머지 모든 문자가 나오든 안 나오든 싹 다 잡을 거임
# 3. 데이터 클린 혹은 데이터 추출 처리
clean_data = pattern.sub('', raw_data) # raw_data에서 패턴에 정의된 모든 문자를 찾아서 ''(빈문자열)로 변경
# 정제된 데이터 체크 (샘플링)
clean_data[:30]
결과값 : ThedogCanisfamiliarisorCanislu
# clean_data에서 a, b, c 등 개별 알파벳의 빈도를 계산하여 results 리스트에 담으시오
# [a의 빈도, b의 빈도, c의 빈도, ..., z의 빈도]
# 검증 -> sum(빈도리스트) == 빈도의 총합 == clean_data의 len()과 동일함
freq = [0]*26
clean_data.lower()
for i in range(len(clean_data)):
freq[ord(clean_data[i].lower())-ord('a')]+=1
print(freq)
결과값 :
[78, 17, 30, 51, 119, 17, 30, 47, 70, 1, 0, 39, 23, 53, 73, 23, 1, 55, 80, 70, 28, 14, 11, 1, 16, 1]
# 데이터 통계, 분석 -> 분산, 표준편차가 크다면 값이 많이 퍼져있다 -> 모델 학습 성능 저하
# 데이터를 정규화 하여 0 ~ 1 사이로 스케일링 처리함 (개별빈도/전체빈도로 모든 빈도 데이터를 처리하여 새로운 리스트로 반환한다)
# -> 람다함수 가능함, 리스트 컴프리헨션 가능함
# 리스트 컴프리헨션
정규화 = [x/sum(freq) for x in freq]
sum(정규화) # 1 나오면 0 ~ 1 사이로 스케일링 성공
# 맵, 람다
정규화 = list(map(lambda x : x/sum(freq), freq))
sum(정규화)
값 : 1.0 (총합 1이므로 성공임)
외장 함수(내장 함수의 상대적 비교 표현)
- 특정 패키지의 함수
- 파이썬을 설치하면 or 특정 패키지를 설치하면 사용 가능
# 파이썬을 설치하면 자동으로 사용 가능한 패키지
# 1. os 모듈 가져오기
import os
# 2. 모듈명.함수() -> 특정 패키지의 함수 사용, 외장함수 사용이 성립됨
os.exit()
- 특정 패키지 설치 후 사용
# 패키지 설치
# pip : 패키지 관리자
pip install 패키지명
# 아나콘다 설치 이후라면
conda install 패키지명
# 한번에 여러개의 패키지 설치(프로젝트 당 관리)
# 이를 기술한 파일 : requirements.txt
pin install -r requirements.txt
등등 다양한 방법이 있음
# 설치 목록 확인
# 코랩이므로 매직코드로 명령어를 리눅스로 전달
!pip list
# 설치된 특정 패키지의 정보를 출력
!pip show pandas
!pip show pymysql
# pandas는 있고 pymysql은 없는 경우
# 패키지 설치
# -q : 로그를 모두 숨겨서 뭐가 설치되는지 생략하고 결과 한줄만 띄움
!pip install pymysql -q
# 설치 되었음
!pip show pymysql
pickle -> ..... -> 모델 덤프 및 로드
- 파이썬의 자료구조 등 타입을 유지한 채로 저장(덤프), 로드 가능함
- 해당 기능은 패키지로 더 확장되어서 ML 모델 저장, 로드 시 사용됨
import pickle
# 덤프 : 메모리 상에 존재하는 리스트 -> 파일에 저장
# w : 쓰기, b : 바이너리 파일로 작업
with open('test.pk', 'wb') as f:
pickle.dump(datas, f) # 리스트 datas 읽어서 파일 f에 저장
# 로드 : 파일을 읽어서 내용을 기반으로 메모리 상에 특정 객체 복원(로드) 함
with open('test.pk', 'rb') as f:
print(pickle.load(f))
결과값 : [1, 2, 3, 4, 5]
사용자 정의 함수
- 기본형
- 람다함수 -> 별도 문법
- 데코레이터 적용된 함수 -> 기존 문법에 가미된 별도 문법
- 제너레이터 적용된 함수
변수의 scope(범위)
- 기본 원칙
- 함수 내부에서 정의된 변수
- 함수 내부에서만 사용 가능 -> 지역(로컬) 변수
- 함수 내부에서만 의미를 가짐, 함수 밖으로 가면 오류 발생
- 절차적코드에서 맨 앞쪽에서 정의된 변수 : 전역(글로벌) 변수
- 함수 내부나, 전역 변수임을 표시하는 키워드
- global 변수명 -> 이 변수는 전역 변수다
- 함수 내부나, 전역 변수임을 표시하는 키워드
- noneloacl 변수
- 함수 안에 함수가 존재하는 구조에서
- 바깥쪽 함수 : outer 함수
- 안쪽 함수 : inner 함수
- outer 함수에서 inner 함수의 변수에 접근할 때 nonlocal 키워드 적용 가능
- 데코레이터, 클로저 형태의 함수에서 볼 수 있음
- 데코레이터 구현 시 체크
- 함수 안에 함수가 존재하는 구조에서
- 함수 내부에서 정의된 변수
# 전역 변수
score = 100
# 함수
def test() :
# 이걸 전역변수로 쓰고싶으면 변수 앞에 global을 붙이면 됨 ex) global score
score = 0 # 지역 변수
score += 1
print(score) # 지역 변수를 출력함
# 함수 사용
test()
# 확인
print(f'-> {score}') # 전역 변수를 출력함
결과값 :
1
-> 100
애너테이션(타입 주석)
- 개요
- 변수, 함수, 클래스 등 타입 가이드 문법
- 타입 주석 or 타입 힌트
- 애너테이션을 적용하면 타입을 무조건 지켜야 하는가?(강제성) -> X
- 다른 타입으로 적용해도 이상 없음, 구현 내부에서 오류가 발생할 수는 있음(타입이 안 맞는 문제로)
- 타입에 대한 설명
- 활용
- 깃허브에 프로젝트 공유 시 타입 힌트를 적용하여 최종 버전 관리
변수 애너테이션
# 변수 애너테이션 적용 예시
# 변수명 : 타입
score : int = 100
name : str = '파이썬'
# 타입 힌트를 무시하고 다른 타입을 넣는다면?
# 잘 들어가고 str로 인식도 됨 -> 강제성은 없음
score : int = 'hi'
score, type(score)
결과값 : ('hi', str)
함수 애너테이션
# 오류 발생 시 바깥에서 원인을 어렴풋이 짐작할 수 있음
# ex) int, int 매개변수인데 int, str 넣었을 때 함수 껍데기만 보고도 알 수 있음
def test_add2(x : int, y : int) -> int : # -> int 리턴 타입을 의미함
'''
parameter
x : int
y : int
returns
x + y 값을 반환함, 타입 : int
'''
return x + y
# 타입을 준수하라는 강제성은 없음
test_add2(1,2), test_add2(1.1, 2.0), test_add2('hello', 'world')
결과값 : (3, 3.1, 'helloworld')
고급 함수- 연급(추후 필요 시 체크)
- 내부 함수
- 클로저 개념
- 데코레이터 구현 시 함께 확인
# 데코레이터 : 기존 함수를 별도 문법이 감싸고 있는 구조
# 반복적으로 같은 기능이 세팅되어야 한다면 유용함
@app.rout('/login', method ="GET")
def login():
pass
'SK플래닛 ai활용 데이터엔지니어 과정 2기 > 파이썬' 카테고리의 다른 글
| 파이썬 - 데이터분석 (0) | 2026.03.09 |
|---|---|
| 파이썬 - 모듈화/모듈가져오기/예외처리 (0) | 2026.03.06 |
| 파이썬-함수 (1) | 2026.03.05 |
| 파이썬 - 흐름제어(3) (0) | 2026.03.05 |
| 파이썬 - 흐름제어(2) (0) | 2026.03.04 |