🐍[python] α„†α…’α„Œα…΅α†¨α„†α…¦α„‰α…©α„ƒα…³ 2 (namedtuple)



λ“€μ–΄κ°€λ©°

Python의 λ„€μž„λ“œ νŠœν”Œ (Named Tuple)은 ML/DLλ“±μ—μ„œ ν•™μŠ΅μ„ μœ„ν•œ 데이터셋 μ „μ²˜λ¦¬ μ‹œμ— 데이터 νƒ€μž…μ— λŒ€ν•œ μž‘μ—…μ„ μ§„ν–‰ν•˜κ±°λ‚˜, μ›Ή κ°œλ°œμ—μ„œ DBμ—μ„œ 자료λ₯Ό κ°€μ Έμ˜¬ λ•Œ 많이 μ‚¬μš©ν•˜λŠ” κ°œλ… 쀑에 ν•˜λ‚˜ μž…λ‹ˆλ‹€. νŠœν”Œμ€ ν•œλ²ˆ μž…λ ₯ν•˜λ©΄ μˆ˜μ •μ΄ μ•ˆλœλ‹€λŠ” νŠΉμ§•μ„ κΈ°μ–΅ν•˜κ³  λ³Έ ν¬μŠ€νŒ…μ„ 읽어 μ£Όμ‹œλ©΄ κ°μ‚¬ν•˜κ² μŠ΅λ‹ˆλ‹€.

μ§€λ‚œ ν¬μŠ€νŒ…μ—μ„œ 객체 λž€ 파이썬의 데이터λ₯Ό 좔상화 ν•œκ²ƒμ΄λΌκ³  μ„€λͺ… ν–ˆμ—ˆμŠ΅λ‹ˆλ‹€. 이λ₯Ό ν™œμš©ν•˜μ—¬ λͺ¨λ“  κ°μ²΄λŠ” id 톡해 확인 ν•  수 있고 valueλŠ” type 으둜 객체 값을 확인 ν•  수 μžˆμŠ΅λ‹ˆλ‹€.

κΈ°μ‘΄ 방법둠

일반적인 νŠœν”Œ

λ‹€μŒκ³Ό 같이 두 점의 μ’Œν‘œλ₯Ό νŠœν”Œ ν˜•νƒœλ‘œ μ €μž₯ ν•  수 μžˆμŠ΅λ‹ˆλ‹€. λ‹€μŒ μ½”λ“œμ˜ λ¬Έμ œμ μ€ 데이터 κ΄€μ μ—μ„œ 봀을 λ•Œ, 1.0 이 λœ»ν•˜λŠ”κ²Œ 무엇인지, μΈμžμ— λŒ€ν•œ 정보λ₯Ό 확인 ν•  수 μ—†μŠ΅λ‹ˆλ‹€.

pt1 = (1.0, 5.0)
pt2 = (2.5, 1.5)

두 점 μ‚¬μ΄μ˜ 거리 κ΅¬ν•˜κΈ°

λ‹€μŒκ³Ό 같이 두 점 μ‚¬μ΄μ˜ 거리λ₯Ό ꡬ할 수 μžˆμŠ΅λ‹ˆλ‹€.

from math import sqrt
l_leng1 = (pt1[0] - pt2[0]) ** 2 + (pt1[1] - pt2[1]) ** 2
l_leng1 = sqrt(l_leng1)
# 3.8078865529319543

λ„€μž„λ“œ νŠœν”Œ (Namedtuple)

λ„€μž„λ“œ νŠœν”Œ μ‚¬μš©ν•΄λ³΄κΈ°

Named tuples are basically easy-to-create, lightweight object types. Named tuple instances can be referenced using object-like variable dereferencing or the standard tuple syntax.

좜처: stackoverflow

λ„€μž„λ“œ νŠœν”Œμ€ νŠœν”Œμ˜ 문법을 λ”°λŠ”λŠ” 객체 라고 ν•©λ‹ˆλ‹€. 이λ₯Ό μ‚¬μš©ν•˜κΈ° μœ„ν•΄μ„œλŠ” collection의 λͺ¨λ“ˆμ„ μ‚¬μš©ν•΄μ•Ό ν•©λ‹ˆλ‹€. μš°λ¦¬λŠ” λ„€μž„λ“œ νŠœν”Œμ„ μ’Œν‘œλ‘œ 생각 ν•  κ²ƒμ΄κΈ°λ•Œλ¬Έμ— namedtuple('Point') κ³Ό 같이 β€˜point’λ₯Ό λͺ…μ‹œμ μœΌλ‘œ μž‘μ„±ν•΄ μ€λ‹ˆλ‹€.

from collections import namedtuple
# λ„€μž„λ“œ νŠœν”Œ μ„ μ–Έ
Point = namedtuple('Point', 'x y')

pt3 = Point(1.0, 5.0)
pt4 = Point(2.5, 1.5)

print(pt3)
print(pt4)
# Point(x=1.0, y=5.0)
# Point(x=2.5, y=1.5)

print(pt3.x, pt3[0])
# 1.0

μœ„ μ½”λ“œμ™€ 같이 pt3 에 λŒ€ν•œ xμ’Œν‘œ 접근은 pt3.x 둜 κ°€λŠ₯ν•©λ‹ˆλ‹€. 즉, μœ μ—°ν•˜κ²Œ μ§κ΄€μ μœΌλ‘œ 데이터 κ΄€μ μ—μ„œ ν•΄λ‹Ή 객체에 λŒ€ν•œ 값을 확인 ν•  수 μžˆλŠ” κ²ƒμ΄μ§€μš”.

이전 ν¬μŠ€νŒ…μ—μ„œ 인덱슀둜 값을 μ ‘κ·Όν•˜λŠ” 것은 μœ„ν—˜ν•˜λ‹€κ³  ν–ˆμŠ΅λ‹ˆλ‹€. λ•Œλ¬Έμ— 두 점 μ‚¬μ΄μ˜ 거리λ₯Ό κ΅¬ν•˜λŠ” 계산도 λ‹€μŒκ³Ό 같이 μˆ˜μ • ν•  수 μžˆμŠ΅λ‹ˆλ‹€. λ‹€μŒκ³Ό 같이 μ½”λ“œκ°€ 보닀 μ§κ΄€μ μœΌλ‘œ 이해가 μ‰½κ²Œ λ°”λ€Œμ˜€μŠ΅λ‹ˆλ‹€.

l_leng2 = (pt3.x - pt4.x) ** 2 + (pt3.y - pt4.y) ** 2
l_leng2 = sqrt(l_leng2)


λ„€μž„λ“œ νŠœν”Œ μ„ μ–Έ 방법

λ‹€μŒκ³Ό 같이 μ—¬λŸ¬ 가지 λ°©λ²•μœΌλ‘œ λ„€μž„λ“œ νŠœν”Œ 선언이 κ°€λŠ₯ν•©λ‹ˆλ‹€. 단, νŠœν”Œμ€ key의 μœ μΌμ„±μ„ 보μž₯ν•΄μ•Όν•˜κΈ° λ•Œλ¬Έμ— 쀑볡을 ν—ˆμš©ν•˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€. μ΄λ•ŒλŠ” rename 인자λ₯Ό True 둜 μ„€μ • ν•΄μ•Ό ν•©λ‹ˆλ‹€.

Point1 = namedtuple('Point', ['x', 'y'])
Point2 = namedtuple('Point', 'x,y')
Point3 = namedtuple('Point', 'x y')


Point4 = namedtuple('Point', 'x y x class') # error: be unique!
Point4 = namedtuple('Point', 'x y x class', rename=True)
# <class '__main__.Point'>

μ΄λ ‡κ²Œ λ„€μž„ν”„ νŠœλΈ” 객체듀을 μƒμ„±ν•˜κ³  λ‹€μŒκ³Ό 같이 μΈμŠ€ν„΄μŠ€λ₯Ό μž…λ ₯ν•΄ μ€λ‹ˆλ‹€. p4 의 값을 μ‚΄νŽ΄ 보면 Point(x=10, y=20, _2=30, _3=40) 와 같이 좜λ ₯λ©λ‹ˆλ‹€. 즉, μ€‘λ³΅λ˜λŠ” Key값은 μžλ™μœΌλ‘œ Key이름을 λ³€κ²½ν•΄μ„œ λ³€μˆ˜λ₯Ό 생성 ν•΄ μ£Όμ—ˆμŠ΅λ‹ˆλ‹€.

# 객체 생성
p1 = Point1(x=10, y=35)
p2 = Point2(20, 40)
p3 = Point3(45, y=20)
p4 = Point4(10, 20, 30, 40)

print(p4)
# Point(x=10, y=20, _2=30, _3=40)


Dict to unpacking

μ΄λ²ˆμ—λŠ” dict νƒ€μž…μ˜ 객체λ₯Ό λ°›μ•„μ„œ λ„€μž„λ“œ νŠœν”Œλ‘œ λ§Œλ“€μ–΄ λ³΄κ² μŠ΅λ‹ˆλ‹€. dict κ³Ό νŠœν”Œμ€ μ–΄λ©΄νžˆ λ‹€λ₯Έ 데이터 νƒ€μž…μž…λ‹ˆλ‹€. λ•Œλ¬Έμ— unpacking κΈ°λŠ₯을 μ‚¬μš©ν•΄μ„œ λ„€μž„λ“œ νŠœν”Œμ— μž…λ ₯ν•΄ μ€λ‹ˆλ‹€.

temp_dict = {'x': 75, 'y': 55}

p5 = Point3(**temp_dict)
# Point(x=75, y=55)


λ„€μž„λ“œ νŠœν”Œ λ©”μ†Œλ“œ

_make : list to namedtuple

리트슀λ₯Ό λ„€μž„λ“œ νŠœν”Œμ˜ μžλ£Œν˜•μœΌλ‘œ λ³€ν™˜ ν•΄μ£ΌλŠ” λ©”μ†Œλ“œλŠ” λ°”λ‘œ _make μž…λ‹ˆλ‹€.

temp = [52, 38]

p4 = Point._make(temp)

_fields : ν•„λ“œ λ„€μž„ 확인

print(p1._fields)
# ('x', 'y')

_asdict(): OrderedDict λ°˜ν™˜

μ •λ ¬λœ λ”•μ…”λ„ˆλ¦¬λ‘œ λ°˜ν™˜ ν•©λ‹ˆλ‹€.

print(p1._asdict())