Tidy Data ์ œ๋Œ€๋กœ ์ดํ•ดํ•˜๊ธฐ — ์ง€์ €๋ถ„ํ•œ ํ‘œ๋ฅผ pandas๋กœ ์ •๋ˆํ•˜๊ธฐ

2026. 8. 31. 14:03ยทAI

์ด๋ฒˆ ๊ฐ•์˜๋Š” "Bad Data"๋ผ๋Š” ๋„“์€ ์ฃผ์ œ์˜€์Šต๋‹ˆ๋‹ค. ์‹ค๋ฌด ๋ฐ์ดํ„ฐ๊ฐ€ ์™œ ์ง€์ €๋ถ„ํ•œ์ง€(์˜คํƒ€ยท๊ฒฐ์ธกยท์ค‘๋ณตยท๋น„ํ‘œ์ค€ยท์ด์ƒ์น˜โ€ฆ), ๊ทธ๊ฑธ ์–ด๋–ป๊ฒŒ ์ฒญ์†Œํ•˜๊ณ (cleaning) ์ฃผ๋ฌด๋ฅด๋Š”์ง€(wrangling), ์—๋Ÿฌ๋ฅผ ์–ด๋–ป๊ฒŒ ํƒ์ง€ยท์˜ˆ๋ฐฉํ•˜๋Š”์ง€๊นŒ์ง€ ํ›‘๊ณ , ๋งˆ์ง€๋ง‰์— Tidy Data๋กœ ๋งˆ๋ฌด๋ฆฌํ•˜๋”๋ผ๊ณ ์š”. ๊ทธ๋ฆฌ๊ณ  ๊ฐ•์˜์™€ ํ•จ๊ป˜ ๋ฐ›์€ tidy-data-master ํด๋”์—๋Š” ์ด Tidy Data ๊ฐœ๋…์˜ ์›์ „ โ€” Hadley Wickham(ํ•ด๋“ค๋ฆฌ ์œ„์ปด)์˜ ๋…ผ๋ฌธ๊ณผ ์‹ค์ œ ์ง€์ €๋ถ„ํ•œ ๋ฐ์ดํ„ฐ ํŒŒ์ผ๋“ค(์ข…๊ตยท์†Œ๋“ ์กฐ์‚ฌ, ๋นŒ๋ณด๋“œ ์ฐจํŠธ, ๊ฒฐํ•ต ํ†ต๊ณ„, ๊ธฐ์ƒ ๊ด€์ธก)์ด ๋“ค์–ด ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค.

๊ฐ•์˜ ์ „์ฒด๋ฅผ ๋‹ค ์˜ฎ๊ธฐ๋ฉด ๋ฌผํƒ€์ง€๋‹ˆ๊นŒ, ์ด ๊ธ€์€ "์ง€์ €๋ถ„ํ•œ ํ‘œ๋ฅผ ์–ด๋–ป๊ฒŒ ๋ถ„์„ ๊ฐ€๋Šฅํ•œ ํ‘œ๋กœ ๋ฐ”๊พธ๋Š”๊ฐ€" ํ•œ ๊ฐˆ๋ž˜์— ์ง‘์ค‘ํ•ฉ๋‹ˆ๋‹ค. Tidy Data๊ฐ€ ๋ญ”์ง€ ์ •์˜๋ถ€ํ„ฐ ์žก๊ณ , ์œ„์ปด์ด ์ •๋ฆฌํ•œ ์ง€์ €๋ถ„ํ•œ ๋ฐ์ดํ„ฐ 5๋Œ€ ์œ ํ˜• ์ค‘ ์ž์ฃผ ๋งŒ๋‚˜๋Š” 3๊ฐ€์ง€๋ฅผ ์‹ค์ œ ๊ฐ•์˜ ๋ฐ์ดํ„ฐ์— pandas๋กœ ์ง์ ‘ ์†๋ด๊ฐ€๋ฉฐ ๋ณผ๊ฒŒ์š”. ์ฐธ๊ณ ๋กœ ํด๋”์˜ README๋Š” R ์ฝ”๋“œ ํŒŒ์ผ(tidy-data.R)์„ ์–ธ๊ธ‰ํ•˜์ง€๋งŒ ์‹ค์ œ ํŒŒ์ผ์€ ๋น ์ ธ ์žˆ์–ด์„œ, ๋…ผ๋ฌธ์˜ R ์˜ˆ์ œ๋ฅผ ์ œ๊ฐ€ pandas๋กœ ์žฌํ˜„ํ–ˆ์Šต๋‹ˆ๋‹ค.

๋ชฉ์ฐจ
  1. ํฐ ๊ทธ๋ฆผ โ€” ์กฐ๊ฐ๋“ค์ด ์–ด๋–ป๊ฒŒ ๋งž๋ฌผ๋ฆฌ๋‚˜
  2. Tidy Data๋ž€ ๋ฌด์—‡์ธ๊ฐ€ (3์›์น™)
  3. ์ง€์ €๋ถ„ํ•œ ๋ฐ์ดํ„ฐ 5๋Œ€ ์œ ํ˜•
  4. melt โ€” ์—ด ์ด๋ฆ„์ด ๊ฐ’์ผ ๋•Œ (์ข…๊ตยท์†Œ๋“ ๋ฐ์ดํ„ฐ)
  5. split โ€” ํ•œ ์—ด์— ๋ณ€์ˆ˜๊ฐ€ ๋‘ ๊ฐœ์ผ ๋•Œ (๊ฒฐํ•ต ๋ฐ์ดํ„ฐ)
  6. pivot โ€” ๊ฐ’์ด ํ–‰ยท์—ด ์–‘์ชฝ์— ํฉ์–ด์กŒ์„ ๋•Œ (๊ธฐ์ƒ ๋ฐ์ดํ„ฐ)
  7. ์น˜ํŠธ์‹œํŠธ & ํ•ต์‹ฌ 4๊ฐ€์ง€

1. ํฐ ๊ทธ๋ฆผ โ€” ์กฐ๊ฐ๋“ค์ด ์–ด๋–ป๊ฒŒ ๋งž๋ฌผ๋ฆฌ๋‚˜

Tidy Data๋Š” ๊ฒฐ๊ตญ "ํ‘œ ํ•˜๋‚˜์— ๋”ฑ ์„ธ ๊ฐ€์ง€ ์งˆ๋ฌธ์„ ๋˜์ง€๊ณ , ์–ด๊ธ‹๋‚˜๋ฉด ์ •ํ•ด์ง„ ๋„๊ตฌ๋กœ ๊ณ ์นœ๋‹ค"๋Š” ์ด์•ผ๊ธฐ์ž…๋‹ˆ๋‹ค. ์„ธ ๊ฐ€์ง€ ์งˆ๋ฌธ์ด tidy์˜ 3์›์น™์ด๊ณ , ์–ด๊ธ‹๋‚˜๋Š” ๋ฐฉ์‹์ด ์ง€์ €๋ถ„ํ•œ ์œ ํ˜•์ด๋ฉฐ, ๊ณ ์น˜๋Š” ๋„๊ตฌ๊ฐ€ meltยทsplitยทpivot์ž…๋‹ˆ๋‹ค. ์•„๋ž˜ ์ง€๋„๊ฐ€ ์ด ๊ธ€์˜ ๋ผˆ๋Œ€์˜ˆ์š”. ์ดํ›„ ๊ฐ ์„น์…˜์ด ์ด ์นธ์„ ํ•˜๋‚˜์”ฉ ์ฑ„์›๋‹ˆ๋‹ค.

์ง€์ €๋ถ„ํ•œ ํ‘œ ์— ์ด ์งˆ๋ฌธ๋“ค์„ ๋˜์ง„๋‹ค
โ–ผ
๋ณ€์ˆ˜ = ์—ด?tidy 3์›์น™ยง2
์—ด ์ด๋ฆ„์ด ๊ฐ’?โ†’ meltwideโ†’long
ํ•œ ์—ด์— ๋ณ€์ˆ˜ 2๊ฐœ?โ†’ splitstr.split
๊ฐ’์ด ํ–‰ยท์—ด ์–‘์ชฝ?โ†’ pivotlongโ†’wide
์„ธ ๋„๊ตฌ๋Š” ์„œ๋กœ ๋ฐ˜๋Œ€ยท๋ณด์™„ ๊ด€๊ณ„ โ€” melt๋Š” ํŽด๊ณ (long), pivot์€ ์ ‘๊ณ (wide), split์€ ์ชผ๊ฐ ๋‹ค
๐Ÿ“Œ ํ•ต์‹ฌ ํ•œ ์ค„ โ€” Tidy Data๋Š” "์˜ˆ์œ ๋ฐ์ดํ„ฐ"๊ฐ€ ์•„๋‹ˆ๋ผ, ๋ถ„์„ ๋„๊ตฌ๊ฐ€ ๋ฐ”๋กœ ๋จน์„ ์ˆ˜ ์žˆ๊ฒŒ ๊ตฌ์กฐ(structure)์™€ ์˜๋ฏธ(semantics)๋ฅผ ์ผ์น˜์‹œํ‚จ ๋ฐ์ดํ„ฐ์ž…๋‹ˆ๋‹ค. ์‚ฌ๋žŒ์ด ๋ณด๊ธฐ ์ข‹์€ ํ‘œ์™€ ๊ธฐ๊ณ„๊ฐ€ ๋‹ค๋ฃจ๊ธฐ ์ข‹์€ ํ‘œ๋Š” ๋‹ค๋ฆ…๋‹ˆ๋‹ค.

2. Tidy Data๋ž€ ๋ฌด์—‡์ธ๊ฐ€ (3์›์น™)

๋จผ์ € ์šฉ์–ด๋ถ€ํ„ฐ ์ •ํ™•ํžˆ ์žก๊ณ  ๊ฐ‘์‹œ๋‹ค. ๊ฐ•์˜ ์Šฌ๋ผ์ด๋“œ์—๋„ ํ•œ ์ค„๋กœ "Tidy Data = Narrow Data = long form"์ด๋ผ๊ณ ๋งŒ ์ ํ˜€ ์žˆ์–ด์„œ, ์ด๊ฒŒ ์ •ํ™•ํžˆ ๋ญ˜ ๋œปํ•˜๋Š”์ง€ ์›์ „์—์„œ ํ™•์ธํ•˜๋Š” ๊ฒŒ ์ค‘์š”ํ•ฉ๋‹ˆ๋‹ค.

Tidy Data (์ •๋ˆ๋œ ๋ฐ์ดํ„ฐ): ๋ฐ์ดํ„ฐ์˜ ์˜๋ฏธ๋ฅผ ๊ตฌ์กฐ์— ๊ทœ์น™์ ์œผ๋กœ ๋Œ€์‘์‹œํ‚จ ํ‘œ โ€” ๋ณ€์ˆ˜๋Š” ์—ด, ๊ด€์ธก์น˜๋Š” ํ–‰์— ์˜ค๋„๋ก ๋งž์ถ˜ ํ˜•ํƒœ.

variable (๋ณ€์ˆ˜): ๊ฐ™์€ ์†์„ฑ์„ ์—ฌ๋Ÿฌ ๋Œ€์ƒ์— ๊ฑธ์ณ ์žฐ ๊ฐ’๋“ค์˜ ๋ฌถ์Œ (์˜ˆ: ํ‚ค, ์˜จ๋„, ์†Œ๋“๊ตฌ๊ฐ„). observation (๊ด€์ธก์น˜): ํ•œ ๋Œ€์ƒ์— ๋Œ€ํ•ด ์žฐ ๊ฐ’๋“ค์˜ ๋ฌถ์Œ (์˜ˆ: ์‚ฌ๋žŒ ํ•œ ๋ช…, ํ•˜๋ฃจ, ๊ฒฝ๊ธฐ ํ•˜๋‚˜).

๋น„์œ ํ•˜์ž๋ฉด, ์—‘์…€์—์„œ ์‚ฌ๋žŒ์ด ๋ณด๊ธฐ ์ข‹์œผ๋ผ๊ณ  ๋งŒ๋“  "์š”์•ฝํ‘œ"๋Š” ์…€ ํ•˜๋‚˜์— ์ •๋ณด๊ฐ€ ์‘์ถ•๋ผ ์žˆ์–ด ๋ˆˆ์œผ๋กœ ์ฝ๊ธฐ์—” ์ข‹์ง€๋งŒ, ์ปดํ“จํ„ฐ๊ฐ€ groupbyยท์ง‘๊ณ„ยท์‹œ๊ฐํ™”๋ฅผ ํ•˜๋ ค๋ฉด ๋งค๋ฒˆ ๋‹ค๋ฅธ ๋ฐฉ์‹์œผ๋กœ ๊ฐ’์„ ๋œฏ์–ด๋‚ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. Tidy Data๋Š” ๊ทธ ๋œฏ์–ด๋‚ด๊ธฐ๋ฅผ ๋‹จ ํ•œ ๊ฐ€์ง€ ๋ฐฉ์‹์œผ๋กœ ํ†ต์ผํ•ด ์ค๋‹ˆ๋‹ค.

์›์ „์€ ์ด๋ ‡๊ฒŒ ์ •์˜ํ•ฉ๋‹ˆ๋‹ค. ์œ„์ปด์€ Tidy Data๋ฅผ ์„ธ ๊ฐ€์ง€ ์›์น™์œผ๋กœ ๋ชป๋ฐ•์Šต๋‹ˆ๋‹ค โ€” ๊ฐ ๋ณ€์ˆ˜๋Š” ํ•˜๋‚˜์˜ ์—ด์„, ๊ฐ ๊ด€์ธก์น˜๋Š” ํ•˜๋‚˜์˜ ํ–‰์„, ๊ฐ ๊ด€์ธก ๋‹จ์œ„ ์œ ํ˜•์€ ํ•˜๋‚˜์˜ ํ‘œ๋ฅผ ์ด๋ฃฌ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ์ด๊ฑด ๊ด€๊ณ„ํ˜• ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์˜ ์ œ3์ •๊ทœํ˜•(3rd normal form)์„ ํ†ต๊ณ„ ์–ธ์–ด๋กœ ๋ฐ”๊ฟ” ์“ด ๊ฒƒ์ด๋ผ๊ณ  ๋ฐํž™๋‹ˆ๋‹ค. (์ถœ์ฒ˜: Hadley Wickham, Tidy Data, Journal of Statistical Software, ยง2.3)

# Tidy Data 3์›์น™ (Wickham, 2014)
# 1. Each variable forms a column.        ๊ฐ ๋ณ€์ˆ˜ = ํ•˜๋‚˜์˜ ์—ด
# 2. Each observation forms a row.         ๊ฐ ๊ด€์ธก์น˜ = ํ•˜๋‚˜์˜ ํ–‰
# 3. Each observational unit forms a table. ๊ฐ ๊ด€์ธก ๋‹จ์œ„ = ํ•˜๋‚˜์˜ ํ‘œ

์—ฌ๊ธฐ์„œ ๊ฐ•์˜์˜ "long form"์ด ์—ฐ๊ฒฐ๋ฉ๋‹ˆ๋‹ค. ๊ฐ™์€ ๋ฐ์ดํ„ฐ๋ฅผ ๋‹ด์•„๋„ wide form(๋„“์€ ํ˜•ํƒœ: ๋ณ€์ˆ˜๋ฅผ ์˜†์œผ๋กœ ํŽผ์ณ ์—ด์„ ๋Š˜๋ฆผ)๊ณผ long form(๊ธด ํ˜•ํƒœ: ๋ณ€์ˆ˜๋ฅผ ์•„๋ž˜๋กœ ์Œ“์•„ ํ–‰์„ ๋Š˜๋ฆผ)์ด ์žˆ๋Š”๋ฐ, tidy๋Š” ๋ณดํ†ต long form ์ชฝ์ž…๋‹ˆ๋‹ค. ์•„๋ž˜ ํ‘œ๊ฐ€ ๊ฐ™์€ ์ •๋ณด์˜ ๋‘ ์–ผ๊ตด์ž…๋‹ˆ๋‹ค.

๊ตฌ๋ถ„wide form (๋„“์€/์ง€์ €๋ถ„ํ•˜๊ธฐ ์‰ฌ์›€)long form (๊ธด/tidy)
๋ชจ์–‘์—ด์ด ์˜†์œผ๋กœ ๋งŽ์Œํ–‰์ด ์•„๋ž˜๋กœ ๋งŽ์Œ
์˜ˆreligion, <$10k, $10-20k, โ€ฆreligion, income, frequency
์‚ฌ๋žŒ ๋ˆˆ์ฝ๊ธฐ ์ข‹์Œ(์š”์•ฝํ‘œ)์žฅํ™ฉํ•ด ๋ณด์ž„
๊ธฐ๊ณ„ ์ฒ˜๋ฆฌ๋งค๋ฒˆ ๋‹ค๋ฅธ ๋ฐฉ์‹์œผ๋กœ ๋œฏ์–ด์•ผ ํ•จgroupbyยท์ง‘๊ณ„ยทํ”Œ๋กฏ ํ•œ ๋ฐฉ์—
๐Ÿ”— ์–ด๋””์— ์“ฐ๋‚˜ โ€” seabornยทplotly ๊ฐ™์€ ์‹œ๊ฐํ™” ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ, groupby().agg() ์ง‘๊ณ„, ๊ทธ๋ฆฌ๊ณ  ML ๋ชจ๋ธ์˜ ์ž…๋ ฅ X ๋งŒ๋“ค๊ธฐ ์ „ ๋‹จ๊ณ„๊ฐ€ ์ „๋ถ€ tidy(long) ํ˜•ํƒœ๋ฅผ ์ „์ œ๋กœ ๋Œ์•„๊ฐ‘๋‹ˆ๋‹ค. "๋ฐ์ดํ„ฐ๊ฐ€ ์™œ ์ด๋ ‡๊ฒŒ ํ”Œ๋กฏ์ด ์•ˆ ๊ทธ๋ ค์ง€์ง€?" ํƒœ๋ฐ˜์€ ํ˜•ํƒœ๊ฐ€ wide๋ผ์„œ์ž…๋‹ˆ๋‹ค.

โ†’ ๊ทธ๋Ÿผ ์‹ค๋ฌด ๋ฐ์ดํ„ฐ๋Š” ์ด 3์›์น™์„ ์–ด๋–ป๊ฒŒ ์–ด๊ธธ๊นŒ์š”? ์œ„์ปด์ด ์ •๋ฆฌํ•œ 5๋Œ€ ์œ ํ˜•์„ ๋ด…๋‹ˆ๋‹ค.

3. ์ง€์ €๋ถ„ํ•œ ๋ฐ์ดํ„ฐ 5๋Œ€ ์œ ํ˜•

์œ„์ปด์€ "ํ–‰๋ณตํ•œ ๊ฐ€์ •์€ ๋‹ค ๋น„์Šทํ•˜์ง€๋งŒ ๋ถˆํ–‰ํ•œ ๊ฐ€์ •์€ ์ €๋งˆ๋‹ค์˜ ๋ฐฉ์‹์œผ๋กœ ๋ถˆํ–‰ํ•˜๋‹ค"๋Š” ํ†จ์Šคํ† ์ด๋ฅผ ๋นŒ๋ ค, ์ง€์ €๋ถ„ํ•œ ๋ฐ์ดํ„ฐ๋„ ์ €๋งˆ๋‹ค์˜ ๋ฐฉ์‹์œผ๋กœ ์ง€์ €๋ถ„ํ•˜๋‹ค๊ณ  ๋งํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฐ๋ฐ ์‹ค์ œ๋กœ ๊ฒช์–ด๋ณด๋ฉด ๋Œ€๋ถ€๋ถ„ ์•„๋ž˜ ๋‹ค์„ฏ ๊ฐ€์ง€๋กœ ์ˆ˜๋ ดํ•˜๋”๋ผ๋Š” ๊ฒŒ ๋…ผ๋ฌธ์˜ ๊ด€์ฐฐ์ž…๋‹ˆ๋‹ค. (์ถœ์ฒ˜: Tidy Data, ยง3)

์ง€์ €๋ถ„ํ•œ ๋ฐ์ดํ„ฐ 5๋Œ€ ์œ ํ˜•
โ–ผ
โ‘  ์—ด์ด๋ฆ„=๊ฐ’๋ณ€์ˆ˜๊ฐ€ ํ—ค๋”์—โ†’ melt
โ‘ก ํ•œ ์—ด = ์—ฌ๋Ÿฌ ๋ณ€์ˆ˜์„ฑ๋ณ„+๋‚˜์ด ๋ญ‰์นจโ†’ split
โ‘ข ํ–‰ยท์—ด ์–‘์ชฝ๋ณ€์ˆ˜๊ฐ€ ํฉ์–ด์งโ†’ pivot
โ‘ฃโ‘ค ํ‘œ ๋ฌธ์ œ์—ฌ๋Ÿฌ ๋‹จ์œ„ ํ•œ ํ‘œ /
ํ•œ ๋‹จ์œ„ ์—ฌ๋Ÿฌ ํ‘œโ†’ ์ •๊ทœํ™”
์ด ๊ธ€์€ ์‹ค๋ฌด ๋นˆ๋„๊ฐ€ ๋†’์€ โ‘ โ‘กโ‘ข์„ ์‹ค์ œ ๋ฐ์ดํ„ฐ๋กœ ๋‹ค๋ฃน๋‹ˆ๋‹ค

โ‘ฃ(ํ•œ ํ‘œ์— ์—ฌ๋Ÿฌ ์ข…๋ฅ˜์˜ ๊ด€์ธก ๋‹จ์œ„๊ฐ€ ์„ž์ž„)์™€ โ‘ค(ํ•œ ๊ด€์ธก ๋‹จ์œ„๊ฐ€ ์—ฌ๋Ÿฌ ํ‘œ์— ์ชผ๊ฐœ์ง)๋Š” ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์ •๊ทœํ™”ยท์กฐ์ธ์˜ ์˜์—ญ์ด๋ผ ๋ณ„๋„ ๊ธ€๋กœ ๋ฏธ๋ฃจ๊ณ , ์—ฌ๊ธฐ์„œ๋Š” ํ‘œ ํ•˜๋‚˜๋ฅผ ์žฌ๊ตฌ์กฐํ™”ํ•˜๋Š” โ‘ โ‘กโ‘ข์— ์ง‘์ค‘ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.

โ†’ ์ฒซ ๋ฒˆ์งธ, ๊ฐ€์žฅ ํ”ํ•œ "์—ด ์ด๋ฆ„์ด ์‚ฌ์‹ค์€ ๊ฐ’"์ธ ๊ฒฝ์šฐ์ž…๋‹ˆ๋‹ค.

4. melt โ€” ์—ด ์ด๋ฆ„์ด ๊ฐ’์ผ ๋•Œ (์ข…๊ตยท์†Œ๋“ ๋ฐ์ดํ„ฐ)

์•ž์˜ ์ง€๋„์—์„œ โ‘ ๋ฒˆ ์นธ์ž…๋‹ˆ๋‹ค. ๋ฐœํ‘œ์šฉ์œผ๋กœ ์˜ˆ์˜๊ฒŒ ๋งŒ๋“  ํ‘œ๋Š” ๋Œ€๊ฐœ ์ด ํ•จ์ •์— ๋น ์ ธ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ฐ•์˜ ๋ฐ์ดํ„ฐ ์ค‘ pew.txt(๋ฏธ๊ตญ Pew Research Center์˜ ์ข…๊ต๋ณ„ ์†Œ๋“ ์กฐ์‚ฌ)๊ฐ€ ๋”ฑ ๊ทธ๋ ‡์Šต๋‹ˆ๋‹ค.

melt (๋…น์ด๋‹ค): ์˜†์œผ๋กœ ํŽผ์ณ์ง„ ์—ฌ๋Ÿฌ ์—ด์„ ๋‘ ๊ฐœ์˜ ์—ด(์ด๋ฆ„ ์—ด + ๊ฐ’ ์—ด)๋กœ ๋…น์—ฌ ์•„๋ž˜๋กœ ์Œ“๋Š” ๋ณ€ํ˜• โ€” wide๋ฅผ long์œผ๋กœ ๋ฐ”๊พธ๋Š” ๋Œ€ํ‘œ ๋„๊ตฌ.

์ง๊ด€์ ์œผ๋กœ๋Š” ์–ผ์Œ ํ‹€(๊ฐ ์นธ=์—ด)์„ ๋…น์—ฌ์„œ ํ•œ ์ค„๊ธฐ ๋ฌผ(์ด๋ฆ„ยท๊ฐ’ ๋‘ ์—ด)๋กœ ํ˜๋ ค๋ณด๋‚ด๋Š” ๊ทธ๋ฆผ์ž…๋‹ˆ๋‹ค. ๊ทธ๋ž˜์„œ ์ด๋ฆ„์ด "melt"์˜ˆ์š”.

๊ณต์‹ ๋ฌธ์„œ๋Š” ์ด๋ ‡๊ฒŒ ์„ค๋ช…ํ•ฉ๋‹ˆ๋‹ค. pandas ๊ณต์‹ ๋ ˆํผ๋Ÿฐ์Šค๋Š” melt๋ฅผ "id_vars๋กœ ์ง€์ •ํ•œ ์‹๋ณ„ ์—ด์€ ๊ทธ๋Œ€๋กœ ๋‘๊ณ , ๋‚˜๋จธ์ง€ ์—ด๋“ค์„ variable/value ๋‘ ์—ด๋กœ unpivotํ•œ๋‹ค"๊ณ  ์ •์˜ํ•ฉ๋‹ˆ๋‹ค. ์•„๋ž˜๊ฐ€ ๊ณต์‹ ๋ฌธ์„œ์— ์‹ค๋ฆฐ ์˜ˆ์ œ ๊ทธ๋Œ€๋กœ์ž…๋‹ˆ๋‹ค. (์ถœ์ฒ˜: pandas.melt)

# pandas ๊ณต์‹ ๋ฌธ์„œ ์˜ˆ์ œ โ€” ๋Œ€์กฐ ๊ธฐ์ค€
df = pd.DataFrame({"A":["a","b","c"], "B":[1,3,5], "C":[2,4,6]})
pd.melt(df, id_vars=["A"], value_vars=["B","C"])
#    A variable  value
# 0  a        B      1     โ† B,C ์—ด ์ด๋ฆ„์ด 'variable' ์—ด์˜ ๊ฐ’์œผ๋กœ ๋‚ด๋ ค์˜ค๊ณ 
# 1  b        B      3        ์›๋ž˜ ์…€ ๊ฐ’์€ 'value' ์—ด๋กœ ์Œ“์ธ๋‹ค
# ...
# 3  a        C      2

๊ฐ•์˜ ๋ฐ์ดํ„ฐ์— ์ ์šฉํ•˜๋ฉด ์ด๋ ‡๊ฒŒ ๋ฉ๋‹ˆ๋‹ค. pew.txt๋Š” religion ํ•œ ์—ด์„ ๋นผ๋ฉด ๋‚˜๋จธ์ง€ ์—ด ์ด๋ฆ„(<$10k, $10-20kโ€ฆ)์ด ์ „๋ถ€ "์†Œ๋“ ๊ตฌ๊ฐ„"์ด๋ผ๋Š” ๋ณ€์ˆ˜์˜ ๊ฐ’์ž…๋‹ˆ๋‹ค. ์ฆ‰ ์—ด ์ด๋ฆ„ ์ž๋ฆฌ์— ๋ฐ์ดํ„ฐ๊ฐ€ ์•‰์•„ ์žˆ๋Š” ๊ฑฐ์ฃ . religion๋งŒ ์‹๋ณ„ ์—ด๋กœ ๊ณ ์ •ํ•˜๊ณ  meltํ•˜๋ฉด tidyํ•ด์ง‘๋‹ˆ๋‹ค.

pew = pd.read_csv("pew.txt", sep="\t")
print(pew.shape)              # (18, 11)  โ† 18๊ฐœ ์ข…๊ต ร— 10๊ฐœ ์†Œ๋“์—ด + religion

tidy = pew.melt(id_vars="religion",
                # ๋‚˜๋จธ์ง€ ์†Œ๋“ ์—ด ์ „๋ถ€๋ฅผ ๋…น์ธ๋‹ค
                var_name="income", value_name="frequency")
print(tidy.shape)             # (180, 3)  โ† 18 ร— 10 = 180 ํ–‰์œผ๋กœ ๊ธธ์–ด์ง
print(tidy.head(4))
#            religion income  frequency
# 0          Agnostic  <$10k         27
# 1           Atheist  <$10k         12
# 2          Buddhist  <$10k         27
# 3          Catholic  <$10k        418

์žฌ๋ฐŒ๋Š” ์ง€์  ํ•˜๋‚˜. ์œ„์ปด์€ R ์‚ฌ๋žŒ์ด๋ผ ๋…ผ๋ฌธ์—์„œ๋Š” reshape2::melt๋ฅผ ์ผ๊ณ , ์ง€๊ธˆ ๊ทธ์˜ ํ›„์† ๋„๊ตฌ tidyr์—์„œ๋Š” pivot_longer()๊ฐ€ ์ด ์—ญํ• ์„ ํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฐ๋ฐ tidyr ๊ณต์‹ ๋ฌธ์„œ์˜ ๋Œ€ํ‘œ ์˜ˆ์ œ๊ฐ€ ๋ฐ”๋กœ ์ด Pew ๋ฐ์ดํ„ฐ(relig_income)์˜ˆ์š”. ๊ฐ•์˜ ๋ฐ์ดํ„ฐ์™€ ๊ณต์‹ ๋ฌธ์„œ ์˜ˆ์ œ๊ฐ€ ๊ฐ™์€ ๋ฐ์ดํ„ฐ์ธ ์…ˆ์ž…๋‹ˆ๋‹ค. (์ถœ์ฒ˜: tidyr::pivot_longer)

# R tidyr ๊ณต์‹ ์˜ˆ์ œ โ€” ์™„์ „ํžˆ ๊ฐ™์€ ๋ฐ์ดํ„ฐ, ๊ฐ™์€ ๊ฒฐ๊ณผ (18ร—11 โ†’ 180ร—3)
relig_income |> pivot_longer(!religion, names_to = "income", values_to = "count")
ํ•ญ๋ชฉpandas ๊ณต์‹ ์˜ˆ์ œ๊ฐ•์˜ ๋ฐ์ดํ„ฐ(pew) ์ ์šฉ์ฐจ์ด ยท ์ด์œ 
์‹๋ณ„ ์—ดid_vars=["A"]id_vars="religion"๊ณ ์ •ํ•  ๋ณ€์ˆ˜ ์ง€์ • โ€” ๊ฐœ๋… ๋™์ผ
๋…น์ผ ์—ดvalue_vars=["B","C"] ๋ช…์‹œ์ƒ๋žต(๋‚˜๋จธ์ง€ ์ „๋ถ€ ์ž๋™)์—ด์ด 10๊ฐœ๋ผ ์ผ์ผ์ด ์•ˆ ์”€ โ€” ์ƒ๋žต ์‹œ id ์™ธ ์ „๋ถ€
๊ฒฐ๊ณผ ์—ด ์ด๋ฆ„variable/value ๊ธฐ๋ณธ๊ฐ’income/frequency์˜๋ฏธ๊ฐ€ ๋“œ๋Ÿฌ๋‚˜๊ฒŒ ๊ฐœ๋ช… โ€” ์‹ค๋ฌด ๊ถŒ์žฅ
๋ชจ์–‘ ๋ณ€ํ™”3ํ–‰ โ†’ 6ํ–‰18ํ–‰ โ†’ 180ํ–‰๋‘˜ ๋‹ค wideโ†’long, ์›๋ฆฌ ๋™์ผ
๐Ÿ’ก var_nameยทvalue_name์„ "variable"/"value" ๊ธฐ๋ณธ๊ฐ’์œผ๋กœ ๋‘์ง€ ๋ง๊ณ  ๊ผญ ์˜๋ฏธ ์žˆ๋Š” ์ด๋ฆ„์œผ๋กœ ๋ฐ”๊พธ์„ธ์š”. 6๊ฐœ์›” ๋’ค์˜ ๋‚ด๊ฐ€ value๊ฐ€ ๋นˆ๋„์ธ์ง€ ๊ธˆ์•ก์ธ์ง€ ๋ชฐ๋ผ ํ—ค๋งต๋‹ˆ๋‹ค.
๐Ÿ”— ์–ด๋””์— ์“ฐ๋‚˜ โ€” ์„ค๋ฌธยทํ†ต๊ณ„์ฒญยท์—‘์…€์—์„œ ๋ฐ›์€ "๊ฐ€๋กœ๋กœ ๊ธด ์š”์•ฝํ‘œ"๋ฅผ ๋ถ„์„์šฉ์œผ๋กœ ๋ฐ”๊ฟ€ ๋•Œ 1์ˆœ์œ„ ๋„๊ตฌ์ž…๋‹ˆ๋‹ค. ์—ฐ๋„๋ณ„ยท์›”๋ณ„ ์—ด์ด ์˜†์œผ๋กœ ์ญ‰ ๋Š˜์–ด์„  ๋งค์ถœํ‘œ๋ฅผ ์‹œ๊ณ„์—ด ๋ถ„์„์šฉ์œผ๋กœ ํŽด๋Š” ๊ฒƒ๋„ ์ •ํ™•ํžˆ ์ด ํŒจํ„ด์ž…๋‹ˆ๋‹ค.

โ†’ melt๋กœ ํˆ๋”๋‹ˆ ์ด๋ฒˆ์—” ์—ด ์ด๋ฆ„ ํ•˜๋‚˜์— ๋ณ€์ˆ˜๊ฐ€ ๋‘ ๊ฐœ ๋ญ‰์ณ ์žˆ๋Š” ๊ฒฝ์šฐ๊ฐ€ ๋‚˜์˜ต๋‹ˆ๋‹ค.

5. split โ€” ํ•œ ์—ด์— ๋ณ€์ˆ˜๊ฐ€ ๋‘ ๊ฐœ์ผ ๋•Œ (๊ฒฐํ•ต ๋ฐ์ดํ„ฐ)

์ง€๋„์˜ โ‘ก๋ฒˆ ์นธ์ž…๋‹ˆ๋‹ค. melt๋ฅผ ํ•˜๊ณ  ๋‚˜๋ฉด variable ์—ด์˜ ๊ฐ’์ด ์‚ฌ์‹ค์€ ์—ฌ๋Ÿฌ ์ •๋ณด๋ฅผ ํ•ฉ์ณ ๋†“์€ ์ฝ”๋“œ์ธ ๊ฒฝ์šฐ๊ฐ€ ์žฆ์Šต๋‹ˆ๋‹ค. ๊ฐ•์˜์˜ tb.csv(WHO ๊ฒฐํ•ต ํ†ต๊ณ„)๊ฐ€ ์ „ํ˜•์ ์ด์—์š”. ์—ด ์ด๋ฆ„์ด new_sp_m1524 ๊ฐ™์€๋ฐ, ์—ฌ๊ธฐ์—” ์„ฑ๋ณ„(m)๊ณผ ๋‚˜์ด๋Œ€(15โ€“24์„ธ)๊ฐ€ ํ•œ ๋ฉ์–ด๋ฆฌ๋กœ ๋ถ™์–ด ์žˆ์Šต๋‹ˆ๋‹ค.

split (์ชผ๊ฐœ๋‹ค): ํ•œ ๋ฌธ์ž์—ด์„ ๊ตฌ๋ถ„ ๊ทœ์น™์— ๋”ฐ๋ผ ์—ฌ๋Ÿฌ ์กฐ๊ฐ์œผ๋กœ ๋‚˜๋ˆ„๋Š” ๊ฒƒ โ€” ์—ฌ๊ธฐ์„œ๋Š” ๋ญ‰์นœ ์—ด ์ด๋ฆ„์„ ์„ฑ๋ณ„ยท๋‚˜์ด๋Œ€ ๋‘ ๋ณ€์ˆ˜๋กœ ๋ถ„๋ฆฌ.

tidy ์›์น™ 1๋ฒˆ("ํ•œ ๋ณ€์ˆ˜ = ํ•œ ์—ด")์„ ์ •๋ฉด์œผ๋กœ ์–ด๊ธด ์ƒํƒœ๋ผ, ๋ถ™์–ด ์žˆ๋Š” ๊ฑธ ๋–ผ์–ด ๊ฐ์ž ์—ด์„ ์ฃผ๋Š” ๊ฒŒ ๋ชฉํ‘œ์ž…๋‹ˆ๋‹ค.

๊ณต์‹ ๋ฌธ์„œ๋Š” ์ด๋ ‡๊ฒŒ ์„ค๋ช…ํ•ฉ๋‹ˆ๋‹ค. pandas Series.str.split์€ expand=True๋ฅผ ์ฃผ๋ฉด ์ชผ๊ฐ  ์กฐ๊ฐ๋“ค์ด ์—ฌ๋Ÿฌ ๊ฐœ์˜ ์—ด๋กœ ํŽผ์ณ์ง„๋‹ค๊ณ  ๋ช…์‹œํ•ฉ๋‹ˆ๋‹ค(๋ถ€์กฑํ•œ ์นธ์€ NaN์œผ๋กœ ์ฑ„์›€). (์ถœ์ฒ˜: pandas.Series.str.split)

# pandas ๊ณต์‹ ๋ฌธ์„œ ์˜ˆ์ œ โ€” expand=True ๋Š” ์กฐ๊ฐ์„ '์—ด'๋กœ ํŽผ์นœ๋‹ค
s = pd.Series(["this is a regular sentence", ...])
s.str.split(expand=True)
#        0    1    2        3         4
# 0   this   is    a  regular  sentence   โ† ๊ณต๋ฐฑ ๊ธฐ์ค€์œผ๋กœ 5๊ฐœ ์—ด ์ƒ์„ฑ

๊ฐ•์˜ ๋ฐ์ดํ„ฐ์— ์ ์šฉํ•˜๋ฉด ์ด๋ ‡๊ฒŒ ๋ฉ๋‹ˆ๋‹ค. tb.csv๋Š” ๊ตฌ๋ถ„์ž๊ฐ€ ์—†์ด m1524์ฒ˜๋Ÿผ ๋”ฑ ๋ถ™์–ด ์žˆ์–ด์„œ, ๊ณต์‹ ์˜ˆ์ œ์ฒ˜๋Ÿผ ๊ตฌ๋ถ„์ž split์ด ์•„๋‹ˆ๋ผ ์œ„์น˜ ๊ธฐ๋ฐ˜ ์Šฌ๋ผ์ด์‹ฑ์ด ๋” ๊น”๋”ํ•ฉ๋‹ˆ๋‹ค(์ฒซ ๊ธ€์ž=์„ฑ๋ณ„, ๋‚˜๋จธ์ง€=๋‚˜์ด๋Œ€). ๋„๊ตฌ๋Š” .str[...]๋กœ ์‚ด์ง ๋ฐ”๊พธ๋˜, "ํ•œ ์—ด์˜ ๋ญ‰์นœ ์ •๋ณด๋ฅผ ๋‘ ๋ณ€์ˆ˜๋กœ ๋–ผ์–ด๋‚ธ๋‹ค"๋Š” ๋ชฉ์ ์€ ๊ณต์‹ ์˜ˆ์ œ์™€ ์™„์ „ํžˆ ๊ฐ™์Šต๋‹ˆ๋‹ค.

tb = pd.read_csv("tb.csv")
m  = tb.melt(id_vars=["iso2","year"],
             var_name="column", value_name="cases").dropna()

# "new_sp_m1524" โ†’ ์ ‘๋‘์–ด ๋–ผ๊ณ  โ†’ ์ฒซ ๊ธ€์ž=์„ฑ๋ณ„, ๋‚˜๋จธ์ง€=๋‚˜์ด๋Œ€
demo    = m["column"].str.replace("new_sp_", "", regex=False)
m["sex"] = demo.str[0]      # 'm' ๋˜๋Š” 'f'
m["age"] = demo.str[1:]     # '1524', '014' โ€ฆ

print(m[["iso2","year","sex","age","cases"]].head(3))
# iso2  year sex  age  cases
#   AE  1999   m  014    4.0     โ† ์„ฑ๋ณ„ยท๋‚˜์ด๋Œ€๊ฐ€ ๊ฐ์ž์˜ ์—ด๋กœ ๋ถ„๋ฆฌ๋จ
#   AE  2000   m  014    2.0
#   AE  2002   m  014    1.0

R ์ชฝ์—์„œ๋Š” ์œ„์ปด์ด ์ด๊ฑธ ์•„์˜ˆ ํ•œ ํ•จ์ˆ˜๋กœ ํก์ˆ˜ํ–ˆ์Šต๋‹ˆ๋‹ค. pivot_longer(names_to = c("sex","age"), names_sep = ...)์ฒ˜๋Ÿผ ํŽด๋ฉด์„œ ๋™์‹œ์— ์ชผ๊ฐœ๊ธฐ๊ฐ€ ๋ฉ๋‹ˆ๋‹ค โ€” melt์™€ split์ด ํ•œ ์Šคํ…์œผ๋กœ ํ•ฉ์ณ์ง„ ์…ˆ์ž…๋‹ˆ๋‹ค. (์ถœ์ฒ˜: tidyr::pivot_longer, names_sep/names_to)

ํ•ญ๋ชฉpandas ๊ณต์‹ ์˜ˆ์ œ๊ฐ•์˜ ๋ฐ์ดํ„ฐ(tb) ์ ์šฉ์ฐจ์ด ยท ์ด์œ 
๋„๊ตฌstr.split(expand=True)str[0] / str[1:] ์Šฌ๋ผ์ด์‹ฑ๊ตฌ๋ถ„์ž๊ฐ€ ์—†์–ด ์œ„์น˜๋กœ ์ž๋ฆ„ โ€” ๋ชฉ์ ์€ ๋™์ผ
๊ฒฐ๊ณผ๊ณต๋ฐฑ๋งˆ๋‹ค N๊ฐœ ์—ดsex, age 2๊ฐœ ์—ด์ชผ๊ฐ  ๋’ค ๊ฐ์ž ์—ด์ด ๋˜๋Š” ์›๋ฆฌ ๊ฐ™์Œ
์„ ํ–‰ ๋‹จ๊ณ„์—†์Œ๋จผ์ € melt ํ•„์š”์—ด ์ด๋ฆ„์ด ๊ฐ’์ด์ž ๋ญ‰์นœ ๋ณ€์ˆ˜ โ€” โ‘ +โ‘ก ๋ณตํ•ฉ
โš ๏ธ ๊ฒฐํ•ต ๋ฐ์ดํ„ฐ์—๋Š” ๊ฐ’์ด 0์ธ ์นธ๊ณผ ๊ฒฐ์ธก(NaN)์ธ ์นธ์ด ์„ž์—ฌ ์žˆ์Šต๋‹ˆ๋‹ค. ๋…ผ๋ฌธ๋„ ์งš๋“ฏ ์ด ๋‘˜์€ ์˜๋ฏธ๊ฐ€ ๋‹ฌ๋ผ์š”("0๊ฑด ํ™•์ธ"๊ณผ "์กฐ์‚ฌ ์•ˆ ํ•จ"). dropna()๋กœ ๊ฒฐ์ธก๋งŒ ๊ฑธ๋Ÿฌ๋‚ด๋˜, 0์„ ๊ฒฐ์ธก๊ณผ ๋ญ‰๋šฑ๊ทธ๋ ค ์ง€์šฐ์ง€ ์•Š๋„๋ก ์ฃผ์˜ํ•˜์„ธ์š”.
๐Ÿ”— ์–ด๋””์— ์“ฐ๋‚˜ โ€” ๋กœ๊ทธยท์„ผ์„œยท์„ค๋ฌธ ํ•„๋“œ์—์„œ 2026-08-31_seoul_temp์ฒ˜๋Ÿผ ๋‚ ์งœยท์ง€์—ญยท์ธก์ •๊ฐ’์ด ํ•œ ์ปฌ๋Ÿผ๋ช…/๋ฌธ์ž์—ด์— ๋ญ‰์ณ ์˜ค๋Š” ๊ฒฝ์šฐ๊ฐ€ ํ”ํ•ฉ๋‹ˆ๋‹ค. ์ด๊ฑธ ๊ฐ ๋ณ€์ˆ˜ ์—ด๋กœ ๋–ผ์–ด์•ผ ํ•„ํ„ฐยท์ง‘๊ณ„๊ฐ€ ๋ฉ๋‹ˆ๋‹ค.

โ†’ ๋งˆ์ง€๋ง‰, ๋ณ€์ˆ˜๊ฐ€ ํ–‰์—๋„ ์žˆ๊ณ  ์—ด์—๋„ ์žˆ์–ด melt๋งŒ์œผ๋กœ๋Š” ์•ˆ ๋˜๋Š” ๊ฐ€์žฅ ๊นŒ๋‹ค๋กœ์šด ๊ฒฝ์šฐ์ž…๋‹ˆ๋‹ค.

6. pivot โ€” ๊ฐ’์ด ํ–‰ยท์—ด ์–‘์ชฝ์— ํฉ์–ด์กŒ์„ ๋•Œ (๊ธฐ์ƒ ๋ฐ์ดํ„ฐ)

์ง€๋„์˜ โ‘ข๋ฒˆ, ๋…ผ๋ฌธ์ด "๊ฐ€์žฅ ๋ณต์žกํ•œ ํ˜•ํƒœ"๋ผ๊ณ  ๋ถ€๋ฅธ ์œ ํ˜•์ž…๋‹ˆ๋‹ค. ๊ฐ•์˜์˜ weather.txt(๋ฉ•์‹œ์ฝ” ๊ธฐ์ƒ๊ด€์ธก์†Œ ์ผ๋ณ„ ๊ธฐ์˜จ)๊ฐ€ ๊ทธ๋ ‡์Šต๋‹ˆ๋‹ค. ๋‚ ์งœ๋Š” d1~d31 ์—ด๋กœ ๊ฐ€๋กœ๋กœ ํฉ์–ด์ ธ ์žˆ๊ณ , ๋™์‹œ์— ์ตœ๊ณ ๊ธฐ์˜จยท์ตœ์ €๊ธฐ์˜จ์ด element ์—ด ์•ˆ์—์„œ TMAX/TMIN ํ–‰์œผ๋กœ ํฉ์–ด์ ธ ์žˆ์–ด์š”. ํ•œ ๋ฐฉํ–ฅ์€ melt๋กœ ํŽด์•ผ ํ•˜๊ณ , ๋‹ค๋ฅธ ๋ฐฉํ–ฅ์€ ๋‹ค์‹œ ์ ‘์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

pivot (๋Œ๋ ค ์„ธ์šฐ๋‹ค / cast): ํ•œ ์—ด์— ์Œ“์—ฌ ์žˆ๋˜ ๊ฐ’์„ ์—ฌ๋Ÿฌ ์—ด๋กœ ํŽผ์ณ ์„ธ์šฐ๋Š” ๋ณ€ํ˜• โ€” melt์˜ ๋ฐ˜๋Œ€. ๋…ผ๋ฌธ ์šฉ์–ด๋กœ๋Š” cast.

melt๊ฐ€ ์—ด์„ ๋…น์—ฌ ์•„๋ž˜๋กœ ์Œ“์•˜๋‹ค๋ฉด, pivot์€ ๊ทธ ์Œ“์ธ ๊ฑธ ๋‹ค์‹œ ์˜†์œผ๋กœ ์„ธ์›๋‹ˆ๋‹ค. ์—ฌ๊ธฐ์„œ๋Š” TMAX/TMIN์ด ์„œ๋กœ ๋‹ค๋ฅธ ๋ณ€์ˆ˜์ธ๋ฐ ํ•œ ์—ด์— ๊ฐ’์œผ๋กœ ๋ˆŒ๋ ค ์žˆ์œผ๋‹ˆ, ๊ฐ์ž์˜ ์—ด๋กœ ์„ธ์›Œ ์˜ฌ๋ ค์•ผ tidyํ•ด์ง‘๋‹ˆ๋‹ค.

๊ณต์‹ ๋ฌธ์„œ๋Š” ์ด๋ ‡๊ฒŒ ์„ค๋ช…ํ•ฉ๋‹ˆ๋‹ค. pandas pivot_table์€ index(ํ–‰์ด ๋  ํ‚ค), columns(์—ด๋กœ ํŽผ์น  ํ‚ค), values(์นธ์„ ์ฑ„์šธ ๊ฐ’)๋กœ long ๋ฐ์ดํ„ฐ๋ฅผ wide๋กœ ์žฌ๊ตฌ์„ฑํ•œ๋‹ค๊ณ  ์ •์˜ํ•ฉ๋‹ˆ๋‹ค. (์ถœ์ฒ˜: pandas.pivot_table)

# pandas ๊ณต์‹ ๋ฌธ์„œ ์˜ˆ์ œ โ€” long์„ index/columns/values๋กœ ์„ธ์šด๋‹ค
pd.pivot_table(df, values=["D","E"], index=["A","C"], aggfunc="mean")
# A,C ์กฐํ•ฉ์ด ํ–‰์ด ๋˜๊ณ , DยทE๊ฐ€ ์—ด์ด ๋˜์–ด ๊ฐ’์ด ์ฑ„์›Œ์ง

๊ฐ•์˜ ๋ฐ์ดํ„ฐ์— ์ ์šฉํ•˜๋ฉด ์ด๋ ‡๊ฒŒ ๋ฉ๋‹ˆ๋‹ค. 2๋‹จ๊ณ„์˜ˆ์š”. โ‘  ๋จผ์ € d1~d31์„ melt๋กœ ํŽด์„œ day ์—ด์„ ๋งŒ๋“ค๊ณ (๊ฐ€๋กœ ํฉ์–ด์ง ํ•ด๊ฒฐ), โ‘ก ๊ทธ๋‹ค์Œ element(TMAX/TMIN)๋ฅผ pivot์œผ๋กœ ์„ธ์›Œ ๋‘ ๊ฐœ์˜ ์—ด๋กœ ์˜ฌ๋ฆฝ๋‹ˆ๋‹ค(์„ธ๋กœ ํฉ์–ด์ง ํ•ด๊ฒฐ).

w = pd.read_csv("weather.txt", sep="\t")

# โ‘  melt: ๋‚ ์งœ ์—ด d1~d31 ์„ 'day' ํ•œ ์—ด๋กœ ํŽธ๋‹ค
long = w.melt(id_vars=["id","year","month","element"],
             var_name="day", value_name="value").dropna()
long["day"] = long["day"].str.replace("d","",regex=False).astype(int)
# ์ด ์‹œ์ : element(TMAX/TMIN)๊ฐ€ ์•„์ง '๊ฐ’'์œผ๋กœ ํ•œ ์—ด์— ๋ˆŒ๋ ค ์žˆ์Œ โ†’ ์•„์ง ์•ˆ tidy

# โ‘ก pivot: element ๋ฅผ ์—ด๋กœ ์„ธ์šด๋‹ค (TMAX, TMIN ๊ฐ์ž ์—ด๋กœ)
wide = long.pivot_table(index=["id","year","month","day"],
                        columns="element", values="value").reset_index()
print(wide.head(3))
#            id  year  month  day   TMAX   TMIN
# MX000017004  2010      1   30  278.0  145.0   โ† ํ•˜๋ฃจ = ํ•œ ํ–‰, ๊ธฐ์˜จ = ๊ฐ ์—ด
# MX000017004  2010      2    2  273.0  144.0   (๊ฐ’์€ 0.1โ„ƒ ๋‹จ์œ„: 278 = 27.8โ„ƒ)
# MX000017004  2010      2    3  241.0  144.0

ํฌ์ธํŠธ๋Š” element ์—ด์ด ๋ณ€์ˆ˜๊ฐ€ ์•„๋‹ˆ๋ผ ๋ณ€์ˆ˜ ์ด๋ฆ„์„ ๋‹ด์€ ์—ด์ด์—ˆ๋‹ค๋Š” ๊ฒ๋‹ˆ๋‹ค. TMAX์™€ TMIN์€ ์„œ๋กœ ๋‹ค๋ฅธ ์ธก์ •๋Ÿ‰์ด๋‹ˆ ๊ฐ์ž ์—ด์ด์–ด์•ผ ๋งž์Šต๋‹ˆ๋‹ค. pivot์œผ๋กœ ์„ธ์šฐ๊ณ  ๋‚˜๋ฉด "ํ•˜๋ฃจ = ํ•œ ํ–‰, ์ตœ๊ณ ยท์ตœ์ €๊ธฐ์˜จ = ๊ฐ ์—ด"์ด๋ผ๋Š” tidy ํ˜•ํƒœ๊ฐ€ ์™„์„ฑ๋ฉ๋‹ˆ๋‹ค. R์—์„œ๋Š” ์ด ๋ฐ˜๋Œ€ ๋ฐฉํ–ฅ์„ pivot_wider()๊ฐ€ ๋งก์Šต๋‹ˆ๋‹ค.

ํ•ญ๋ชฉpandas ๊ณต์‹ ์˜ˆ์ œ๊ฐ•์˜ ๋ฐ์ดํ„ฐ(weather) ์ ์šฉ์ฐจ์ด ยท ์ด์œ 
ํ–‰ ํ‚คindex=["A","C"]index=[id,year,month,day]๊ด€์ธก์น˜๋ฅผ ์‹๋ณ„ํ•˜๋Š” ํ‚ค โ€” ๊ฐœ๋… ๋™์ผ
ํŽผ์น  ํ‚คcolumns ๋ฏธ์‚ฌ์šฉ(์˜ˆ์ œ)columns="element"TMAX/TMIN์„ ์—ด๋กœ ์„ธ์šฐ๋Š” ๊ฒŒ ํ•ต์‹ฌ
์„ ํ–‰ ๋‹จ๊ณ„์—†์Œmelt ๋จผ์ €๊ฐ€๋กœยท์„ธ๋กœ ์–‘์ชฝ ํฉ์–ด์ง์ด๋ผ melt+pivot 2๋‹จ
๋ฐฉํ–ฅlong โ†’ widelong โ†’ widemelt์˜ ์—ญ์—ฐ์‚ฐ โ€” ์›๋ฆฌ ๋™์ผ
๐Ÿ’ก pivot vs pivot_table: ๊ฐ™์€ (ํ–‰,์—ด) ์กฐํ•ฉ์— ๊ฐ’์ด ํ•˜๋‚˜๋ฟ์ด๋ฉด pivot, ์—ฌ๋Ÿฌ ๊ฐœ๋ผ ์ง‘๊ณ„(meanยทsum ๋“ฑ)๊ฐ€ ํ•„์š”ํ•˜๋ฉด pivot_table์„ ์”๋‹ˆ๋‹ค. ์ค‘๋ณต ํ‚ค์—์„œ pivot์€ ์—๋Ÿฌ, pivot_table์€ aggfunc๋กœ ๋ญ‰๊ฐญ๋‹ˆ๋‹ค.
๐Ÿ”— ์–ด๋””์— ์“ฐ๋‚˜ โ€” "long์œผ๋กœ ์ €์žฅ, wide๋กœ ํ‘œํ˜„"์ด ์‹ค๋ฌด ๊ณต์‹์ž…๋‹ˆ๋‹ค. DBยท์ˆ˜์ง‘์€ tidy(long)๋กœ ์Œ“์•„๋‘๊ณ , ๋ฆฌํฌํŠธ ํ”ผ๋ฒ—ํ…Œ์ด๋ธ”์ด๋‚˜ ์ƒ๊ด€ํ–‰๋ ฌยทํžˆํŠธ๋งต์„ ๊ทธ๋ฆด ๋•Œ๋งŒ pivot์œผ๋กœ ์ž ๊น wide๋กœ ์„ธ์›๋‹ˆ๋‹ค.

โ†’ ์„ธ ๋„๊ตฌ๋ฅผ ํ•œ ์žฅ์œผ๋กœ ์ •๋ฆฌํ•˜๊ณ  ๋‹ซ๊ฒ ์Šต๋‹ˆ๋‹ค.

์น˜ํŠธ์‹œํŠธ & ํ•ต์‹ฌ 4๊ฐ€์ง€

์ฆ์ƒ (์ง€์ €๋ถ„ํ•œ ์œ ํ˜•)๋„๊ตฌpandas ํŒจํ„ด
์—ด ์ด๋ฆ„์ด ์‚ฌ์‹ค์€ ๊ฐ’ (wide)meltdf.melt(id_vars=..., var_name=..., value_name=...)
ํ•œ ์—ด์— ๋ณ€์ˆ˜๊ฐ€ ์—ฌ๋Ÿฌ ๊ฐœsplits.str.split(sep, expand=True) / s.str[a:b]
๊ฐ’์ด ํ–‰ยท์—ด ์–‘์ชฝ์— ํฉ์–ด์งpivotdf.pivot_table(index=..., columns=..., values=...)
(์ฐธ๊ณ ) longโ†’wide ๋˜๋Œ๋ฆฌ๊ธฐpivotmelt์˜ ์—ญ์—ฐ์‚ฐ โ€” R์€ pivot_wider()
๐Ÿ“Œ ํ•ต์‹ฌ 4๊ฐ€์ง€
1. Tidy = ๋ณ€์ˆ˜๋Š” ์—ด, ๊ด€์ธก์น˜๋Š” ํ–‰, ๊ด€์ธก๋‹จ์œ„๋Š” ํ‘œ (Wickham 3์›์น™ = DB ์ œ3์ •๊ทœํ˜•).
2. ์‚ฌ๋žŒ์ด ๋ณด๊ธฐ ์ข‹์€ ํ‘œ(wide)์™€ ๊ธฐ๊ณ„๊ฐ€ ๋‹ค๋ฃจ๊ธฐ ์ข‹์€ ํ‘œ(long)๋Š” ๋‹ค๋ฅด๋‹ค โ€” ๋ถ„์„์€ long์ด ๊ธฐ๋ณธ.
3. ์ง€์ €๋ถ„ํ•จ์€ ๋Œ€๋ถ€๋ถ„ ์—ด์ด๋ฆ„=๊ฐ’ / ํ•œ ์—ด์— ์—ฌ๋Ÿฌ ๋ณ€์ˆ˜ / ํ–‰ยท์—ด ์–‘์ชฝ ํฉ์–ด์ง์œผ๋กœ ์ˆ˜๋ ดํ•œ๋‹ค.
4. ๊ณ ์น˜๋Š” ๋„๊ตฌ๋Š” melt(ํŽด๊ธฐ) ยท split(์ชผ๊ฐœ๊ธฐ) ยท pivot(์„ธ์šฐ๊ธฐ) ์…‹์ด๋ฉด ์ถฉ๋ถ„ํ•˜๋‹ค.
๐Ÿ’ก ๊ฐ•์˜์˜ ๋‹ค๋ฅธ ๋ช…์–ธ๋„ ๊ฐ™์€ ์ด์•ผ๊ธฐ์ž…๋‹ˆ๋‹ค โ€” "๋ฐ์ดํ„ฐ ๋ถ„์„์˜ 80%๋Š” ๋ฐ์ดํ„ฐ ์ฒญ์†Œ์™€ ์ค€๋น„์— ์“ฐ์ธ๋‹ค"(Dasu & Johnson, ์œ„์ปด ๋…ผ๋ฌธ ์„œ๋‘ ์ธ์šฉ). tidy ๊ตฌ์กฐ๋ฅผ ์ฒ˜์Œ์— ์žก์•„๋‘๋ฉด ๊ทธ 80%๊ฐ€ ํ›จ์”ฌ ๊ฐ€๋ฒผ์›Œ์ง‘๋‹ˆ๋‹ค.

์ฐธ๊ณ  ์ž๋ฃŒ

  • Hadley Wickham, Tidy Data โ€” Journal of Statistical Software (tidy 3์›์น™ ยง2.3, 5๋Œ€ ์œ ํ˜• ยง3์˜ ์›์ „)
  • pandas ๊ณต์‹ ๋ฌธ์„œ โ€” melt ยท pivot_table ยท Series.str.split
  • tidyr(R, Wickham) ๊ณต์‹ ๋ฌธ์„œ โ€” pivot_longer (melt/split์˜ ํ›„์†, relig_income ์˜ˆ์ œ)
  • ๋ฐ์ดํ„ฐ ์ถœ์ฒ˜: ๊ฐ•์˜ ์ฒจ๋ถ€ tidy-data-master/data (pewยทtbยทweather โ€” WHOยทPewยทGHCN ์›์ž๋ฃŒ)

'AI' ์นดํ…Œ๊ณ ๋ฆฌ์˜ ๋‹ค๋ฅธ ๊ธ€

๋ฐ์ดํ„ฐ ์ „์ฒ˜๋ฆฌ, ์™œ ๋ชจ๋ธ๋ณด๋‹ค ๋จผ์ €์ธ๊ฐ€ โ€” sklearn์œผ๋กœ ์ •๋ฆฌํ•˜๋Š” ML ์ „์ฒ˜๋ฆฌ ํŒŒ์ดํ”„๋ผ์ธ  (0) 2026.09.01
Bad Data ์ œ๋Œ€๋กœ ๋‹ค๋ฃจ๊ธฐ โ€” ๋ฐ์ดํ„ฐ ํด๋ฆฌ๋‹ยท๋žญ๊ธ€๋ง๋ถ€ํ„ฐ ML ๋ฐ์ดํ„ฐ ๋ˆ„์ˆ˜๊นŒ์ง€  (0) 2026.08.31
NumPy๋Š” ์™œ ๋น ๋ฅธ๊ฐ€ โ€” ndarray ๋ฉ”๋ชจ๋ฆฌ ๋ชจ๋ธ๋ถ€ํ„ฐ einsum๊นŒ์ง€  (0) 2026.08.27
AI Agent ๋ถ€ํŠธ์บ ํ”„ Day 14 - ๋ธŒ๋ผ์šฐ์ €๊ฐ€ ํ•˜๋Š” ์ผ์„ ํŒŒ์ด์ฌ์œผ๋กœ โ€” Selenium ์ฟ ํ‚ค ์ถ”์ถœ + ๋‚ด๋ถ€ API ์ง์ ‘ ํ˜ธ์ถœ  (0) 2026.08.20
์ผ€์–ด๋…ธํŠธAI ์‹œ์Šคํ…œ ์„ค๊ณ„ v1  (0) 2026.08.20
'AI' ์นดํ…Œ๊ณ ๋ฆฌ์˜ ๋‹ค๋ฅธ ๊ธ€
  • ๋ฐ์ดํ„ฐ ์ „์ฒ˜๋ฆฌ, ์™œ ๋ชจ๋ธ๋ณด๋‹ค ๋จผ์ €์ธ๊ฐ€ — sklearn์œผ๋กœ ์ •๋ฆฌํ•˜๋Š” ML ์ „์ฒ˜๋ฆฌ ํŒŒ์ดํ”„๋ผ์ธ
  • Bad Data ์ œ๋Œ€๋กœ ๋‹ค๋ฃจ๊ธฐ — ๋ฐ์ดํ„ฐ ํด๋ฆฌ๋‹·๋žญ๊ธ€๋ง๋ถ€ํ„ฐ ML ๋ฐ์ดํ„ฐ ๋ˆ„์ˆ˜๊นŒ์ง€
  • NumPy๋Š” ์™œ ๋น ๋ฅธ๊ฐ€ — ndarray ๋ฉ”๋ชจ๋ฆฌ ๋ชจ๋ธ๋ถ€ํ„ฐ einsum๊นŒ์ง€
  • AI Agent ๋ถ€ํŠธ์บ ํ”„ Day 14 - ๋ธŒ๋ผ์šฐ์ €๊ฐ€ ํ•˜๋Š” ์ผ์„ ํŒŒ์ด์ฌ์œผ๋กœ — Selenium ์ฟ ํ‚ค ์ถ”์ถœ + ๋‚ด๋ถ€ API ์ง์ ‘ ํ˜ธ์ถœ
harang Lee
harang Lee
404...
  • harang Lee
    SkyWith628
    harang Lee
  • ์ „์ฒด
    ์˜ค๋Š˜
    ์–ด์ œ
    • ๋ถ„๋ฅ˜ ์ „์ฒด๋ณด๊ธฐ (122) N
      • AI (51) N
      • C (20)
      • C++ (23)
      • iOS (18)
      • Python (1)
      • AWS (4)
      • Git (1)
  • ๋ธ”๋กœ๊ทธ ๋ฉ”๋‰ด

    • ํ™ˆ
    • ํƒœ๊ทธ
    • ๋ฐฉ๋ช…๋ก
  • ๋งํฌ

    • GitHub
  • ๊ณต์ง€์‚ฌํ•ญ

  • ์ธ๊ธฐ ๊ธ€

  • ํƒœ๊ทธ

    Cํ”„๋กœ๊ทธ๋ž˜๋ฐ
  • ์ตœ๊ทผ ๋Œ“๊ธ€

  • ์ตœ๊ทผ ๊ธ€

  • hELLOยท Designed By์ •์ƒ์šฐ.v4.10.4
harang Lee
Tidy Data ์ œ๋Œ€๋กœ ์ดํ•ดํ•˜๊ธฐ — ์ง€์ €๋ถ„ํ•œ ํ‘œ๋ฅผ pandas๋กœ ์ •๋ˆํ•˜๊ธฐ
์ƒ๋‹จ์œผ๋กœ

ํ‹ฐ์Šคํ† ๋ฆฌํˆด๋ฐ”