λ³Έλ¬Έ λ°”λ‘œκ°€κΈ°
πŸ’‘ Data Analysis/πŸ“‚ Project - Analysis of KakaoTalk (end)

[DA][Python] μΉ΄μΉ΄μ˜€ν†‘ λŒ€ν™” λ‚΄μš© 뢄석 κΈ°λŠ₯ ν•¨μˆ˜ κ΅¬ν˜„ (3-1)

by Sun A 2024. 7. 16.

μ•ž κ²Œμ‹œκΈ€μ—μ„œ μΉ΄μΉ΄μ˜€ν†‘ 원본 λŒ€ν™” λ‚΄μš©μ„ λ‚΄λ €λ°›μ•„ μ „μ²˜λ¦¬ν•˜λŠ” 과정을 μž‘μ„±ν•˜κ³  ν•¨μˆ˜λ‘œ κ΅¬ν˜„ν•΄λ³΄μ•˜λ‹€.

β–Ό κ²Œμ‹œλ¬Ό ν™•μΈν•˜κΈ°

 

[DA][Python] (2μ°¨ 섀계 및 μ™„μ„±) μΉ΄μΉ΄μ˜€ν†‘ λŒ€ν™” 데이터 μ „μ²˜λ¦¬ μ½”λ“œ μˆ˜μ • 섀계

ν˜„μž¬ ν•΄λ‹Ή λ‚΄μš©μ€ ν”Όλ“œλ°±μ„ λ°›μ•„ μ½”λ“œ μž‘μ„±μ„ μ™„λ£Œν•˜μ˜€μœΌλ©° μ΅œμ’… μ™„μ„±λœ μ½”λ“œμ— λŒ€ν•œ μ„€λͺ…이닀.μˆ˜μ •μ‚¬ν•­1. ν•¨μˆ˜λͺ…을 λͺ…ν™•ν•˜κ²Œ λ³€κ²½2. 원본 데이터에 μ‘΄μž¬ν•˜λŠ” μ„œλ‘œ λ‹€λ₯Έ ν˜•μ‹μ˜ 라인 두 가지에

sundery.tistory.com

 

μ²˜μŒμ— λ§Œλ“  것은 μ‚¬μš©μžλ³„ λŒ€ν™” λΉˆλ„ λΆ„μ„μ΄μ—ˆκ³  λ‘λ²ˆμ§Έμ— λ§Œλ“  것은 μ‚¬μš©μžλ³„ 이λͺ¨ν‹°μ½˜ μ‚¬μš© λΉˆλ„ λΆ„μ„μ΄μ—ˆλ‹€.

두 κ°€μ§€ 쑰건을 ν•„ν„°λ§ν•˜κ³  ν•΄λ‹Ήν•˜λŠ” ν–‰μ˜ 개수만 μ„Έμ„œ 좜λ ₯ν•˜λ©΄ λ˜λŠ” μ‰¬μš΄ ν•¨μˆ˜μ˜€λ‹€.

이번 μ„Έ 번째둜 λ§Œλ“€κ²Œ 될 ν•¨μˆ˜λŠ” μ‹œκ°„λŒ€λ³„ 각 μ‚¬μš©μž ν™œλ™ λΉˆλ„λ₯Ό 뢄석할 것이닀. 


뢄석 λ‚΄μš©

μ‹œκ°„λŒ€λ³„ 각 μ‚¬μš©μž ν™œλ™ λΉˆλ„ 뢄석

μš°μ„  μ‹œκ°„μ˜ λ²”μœ„λ₯Ό μ •ν•œλ‹€. 

'μƒˆλ²½', 'μ˜€μ „', 'μ˜€ν›„', '저녁' μ΄λ ‡κ²Œ 4개의 λ²”μœ„λ‘œ μ •ν•˜κ³  μ‹œκ°„μ„ λ°°λΆ„ν•œλ‹€. 

μƒˆλ²½ 00:00 ~ 06:00
μ˜€μ „ 06:00 ~ 12:00
μ˜€ν›„ 12:00 ~ 18:00
저녁 18:00 ~ 24:00

 

μš°μ„  ν•¨μˆ˜λ₯Ό μ •μ˜ν•΄μ€€λ‹€. μ‹œκ°„ 별 ν™œλ™ λΉˆλ„λ₯Ό λΆ„μ„ν•˜λŠ” 것이기 λ•Œλ¬Έμ— analyze_activity_by_timeμ΄λΌλŠ” ν•¨μˆ˜λ₯Ό μ‚¬μš©ν•œλ‹€.

def analyze_activity_by_time(data):

 

μ‹œκ°„λŒ€λ³„λ‘œ λ‚˜λˆ μ„œ 계산해야 ν•˜κΈ° λ•Œλ¬Έμ— Time μΉΌλŸΌμ—μ„œ Hours만 μΆ”μΆœν•œλ‹€.

df['Hours'] = pd.to_datetime(df['Time'], format='%H:%M').dt.hour
  •  μ›λ³Έ 데이터가 12:00 와 같은 ν˜•μ‹μ΄κΈ° λ•Œλ¬Έμ— 이 format을 datetime으둜 λ³€ν™˜ν•΄μ£ΌλŠ” μ½”λ“œλ₯Ό μž‘μ„±ν•œλ‹€.
  • format = '%H:%M'
  • μ—¬κΈ°μ„œ hour만 μΆ”μΆœν•˜μ—¬ df의 μΉΌλŸΌμ— 'Hours'둜 λ„£λŠ”λ‹€

 

Hoursλ₯Ό 4개의 λ²”μœ„λ‘œ λ‚˜λˆˆλ‹€.

μ‹œκ°„μ˜ κ²½κ³„λŠ” μœ„μ— λ‚˜νƒ€λ‚Έ 듯이 μƒˆλ²½, μ˜€μ „, μ˜€ν›„, μ €λ…μœΌλ‘œ λ‚˜λˆ„κΈ° λ•Œλ¬Έμ— boundaryλΌλŠ” λ¦¬μŠ€νŠΈμ— 경계값을 λ„£λŠ”λ‹€. 

그리고 각 κ²½κ³„κ°’μ˜ 이름을 μ‚½μž…ν•΄μ€€λ‹€

boundary = [0, 6, 12, 18, 24]
labels = ['μƒˆλ²½', 'μ˜€μ „', 'μ˜€ν›„', '저녁']

boundary둜 각 μ‹œκ°„λŒ€μ˜ 경계λ₯Ό λ‚˜νƒ€λ‚΄μ—ˆκΈ° λ•Œλ¬Έμ— pd.cut μ΄λΌλŠ” ν•¨μˆ˜λ₯Ό μ‚¬μš©ν•˜μ—¬ μ•„λž˜μ™€ 같은 κ²°κ³Όκ°€ λ‚˜μ˜¬ 수 μžˆλ‹€.

  1. μƒˆλ²½ : 00μ‹œ(포함) ~ 06μ‹œ(미만)
  2. μ˜€μ „ : 06μ‹œ(포함) ~ 12μ‹œ(미만)
  3. μ˜€ν›„ : 12μ‹œ(포함) ~ 18μ‹œ(미만)
  4. 저녁 : 18μ‹œ(포함) ~ 24μ‹œ(미만)

 

λ§ˆμ§€λ§‰μœΌλ‘œ λ‚˜λˆˆ λ²”μœ„ 값을 칼럼으둜 λ„£κ³  (칼럼λͺ… : 'Time_Parts')  νŒλ‹€μŠ€μ˜ ν•¨μˆ˜ cut을 κ°€μ Έμ™€μ„œ labelsλ₯Ό μ‚½μž…ν•œλ‹€.

df['Time_Parts'] = pd.cut(df['Hours'], bins=boundary, labels=labels, right=True, include_lowest=True)
  • Time_Parts에 λ“€μ–΄κ°ˆ λ‚΄μš©μ€ Hours 칼럼의 값을 κ°€μ Έμ˜¨λ‹€λŠ” μ˜λ―Έμ—μ„œ df['Hours'] μž…λ ₯
  • ꡬ간을 λ‚˜λˆ„λŠ” κΈ°μ€€κ°’λ“€μ΄λ‚˜ κ΅¬κ°„μ˜ 개수 값을 bins에 μ‚½μž…
  • 각 ꡬ간에 뢙일 λ ˆμ΄λΈ”μ„ μΆ”κ°€ν•œλ‹€. (μ•žμ„œ μ •μ˜ν•œ 값을 λ„£μœΌλ©΄ λœλ‹€.)
    • right = True : κ΅¬κ°„μ˜ 였λ₯Έμͺ½ 끝을 ν¬ν•¨ν•œλ‹€.
    • right = False : κ΅¬κ°„μ˜ 였λ₯Έμͺ½ 끝을 ν¬ν•¨ν•˜μ§€ μ•ŠλŠ”λ‹€.
    • include_lowest=True : κ΅¬κ°„μ˜ κ°€μž₯ μž‘μ€ 값을 ν¬ν•¨ν•œλ‹€.
    • include_lowest=False : κ΅¬κ°„μ˜ κ°€μž₯ μž‘μ€ 값을 ν¬ν•¨ν•˜μ§€ μ•ŠλŠ”λ‹€. 

 

이제 κ³„μ‚°ν•˜λ €λŠ” 값인 μ‹œκ°„λŒ€λ³„ ν™œλ™ λΉˆλ„ 집계 값을 좜λ ₯ν•œλ‹€.

activity_by_time = df.groupby(['Name', 'Time_Parts']).size().reset_index(name='Count_Messages')
return activity_by_time
  • groupbyλ₯Ό 톡해 'Time_Parts'와 'Name' 두 κ°€μ§€ μ»¬λŸΌμ„ κΈ°μ€€μœΌλ‘œ κ·Έλ£Ήν™”κ°€ κ°€λŠ₯ν•˜λ‹€.
  • 각 κ·Έλ£Ήν™”λœ 그룹의 λΉˆλ„λ₯Ό κ³„μ‚°ν•˜κΈ° μœ„ν•΄ size() ν•¨μˆ˜λ₯Ό μž…λ ₯ν•œλ‹€.
  • 그리고 인덱슀λ₯Ό μ΄ˆκΈ°ν™”ν•˜μ—¬ λ°μ΄ν„°ν”„λ ˆμž„ ν˜•νƒœλ‘œ λ³€ν™˜ν•˜λŠ”λ° size()값에 Count_Messages λΌλŠ” 칼럼λͺ…을 λΆ™μ—¬μ£Όλ©΄ λœλ‹€.

좜λ ₯값은 μ•„λž˜μ™€ κ°™λ‹€.

 


사싀 μ›λž˜ μ²˜μŒμ—λŠ” ν‘œ ν˜•μ‹μœΌλ‘œ 좜λ ₯ν•˜κΈ° μœ„ν•΄ unstack(fill_value=0)ν•¨μˆ˜λ₯Ό μ¨μ„œ ν–‰κ³Ό μ—΄ 인덱슀λ₯Ό μ§€μ •ν•˜μ—¬ 좜λ ₯λ˜λ„λ‘ ν•˜μ˜€λ‹€. 

ν•˜μ§€λ§Œ μœ„μ™€ 같은 ν˜•μ‹μœΌλ‘œ 좜λ ₯ν•˜λ©΄ μ§€κΈˆ λ‹Ήμž₯ λ³΄κΈ°μ—λŠ” νŽΈν•˜μ§€λ§Œ 데이터 뢄석 μ‹œμ—λŠ” μ’‹μ§€ μ•ŠκΈ° λ•Œλ¬Έμ— μ‚­μ œν•˜κ³  κ°œλ³„ 값이 νŠœν”Œμ— 좜λ ₯λ˜λ„λ‘ 값을 ν˜•μ„±ν•˜μ˜€λ‹€.

 


전체 μ™„μ„± μ½”λ“œ

#μ‹œκ°„λŒ€λ³„ 각 μ‚¬μš©μž ν™œλ™ λΉˆλ„ 뢄석
def analyze_activity_by_time(data):
    """λ°μ΄ν„°ν”„λ ˆμž„μ—μ„œ μ‹œκ°„λŒ€λ³„ ν™œλ™μ„ 뢄석"""
    
    #μ‹œκ°„λŒ€ Hours 칼럼으둜 μΆ”μΆœ
    df['Hours'] = pd.to_datetime(df['Time'], format='%H:%M').dt.hour
    
    #μ‹œκ°„λŒ€ 4개 λ²”μœ„λ‘œ λ‚˜λˆ„κΈ°
    boundary = [0, 6, 12, 18, 24]
    labels = ['μƒˆλ²½', 'μ˜€μ „', 'μ˜€ν›„', '저녁']
    df['Time_Parts'] = pd.cut(df['Hours'], bins=boundary, labels=labels, right=False, include_lowest=True)
    
    #μ‹œκ°„λŒ€λ³„ ν™œλ™ λΉˆλ„ 집계
    activity_by_time = df.groupby(['Name', 'Time_Parts']).size().reset_index(name='Count_Messages')
    return activity_by_time

df = generate_dataframe(data)
analyze_activity_by_time(df)