Python - 문제 풀이

Ryan·2025년 1월 21일

Python/Pandas

목록 보기
1/23

데이터 분석 문제 Q1~Q14

이번 글에서는 주어진 데이터셋을 활용한 20가지 분석 문제를 정리하고, 각 문제의 해결 방법을 설명합니다. 이는 데이터 분석에 익숙해지고 실력을 키우기 위한 좋은 연습 자료입니다.


Q1. 인기 동영상 제작 횟수가 많은 채널 상위 10개 출력하기

# 채널별 인기 동영상 제작 횟수 계산
popular_channels = df.channelTitle.value_counts().head(10)
print(popular_channels)

이 코드는 channelTitle 컬럼에서 등장 횟수를 세어 상위 10개 채널을 출력합니다.

출력 예시:

짤툰                       372
파뿌리                      318
SPOTV                    318
런닝맨 - 스브스 공식 채널          313
엠뚜루마뚜루 : MBC 공식 종합 채널    293
장삐쭈                      283
BANGTANTV                275
채널 십오야                   274
이과장                      258
총몇명                      255

Q2. 논란으로 인기 동영상이 된 채널 확인하기

# dislikes 수가 likes 수보다 많은 동영상의 채널명 확인
controversial_channels = df[df['likes'] < df['dislikes']]['channelTitle'].unique()
print(controversial_channels)

이 코드는 likes보다 dislikes가 많은 데이터를 필터링하여, 해당 채널명을 출력합니다.

출력 예시:

['핫도그TV', 'ASMR 애정TV', '하얀트리HayanTree', ...]

Q3. 채널명을 바꾼 채널의 개수 구하기

# channelId를 기준으로 채널명 변경 여부 확인
change = df[['channelTitle', 'channelId']].drop_duplicates().channelId.value_counts()
target = change[change > 1]
print(len(target))

channelId는 고유 식별자로 사용되며, 동일한 channelId에 대해 다른 channelTitle이 존재하는 경우를 확인합니다.

출력: 71


Q4. 일요일에 가장 많은 영상 종류(categoryId) 찾기

# 일요일의 categoryId 확인
df['trending_date2'] = pd.to_datetime(df['trending_date2'])
most_common_category = df.loc[df['trending_date2'].dt.day_name() == 'Sunday'].categoryId.value_counts().index[0]
print(most_common_category)

trending_date2 컬럼을 날짜로 변환하고, 일요일에 해당하는 categoryId 중 가장 많이 등장한 값을 출력합니다.

출력: 24


Q5. 요일별 categoryId의 개수 구하기

group = df.groupby([df['trending_date2'].dt.day_name(), 'categoryId'], as_index=False).size()
answer = group.pivot(index='categoryId', columns='trending_date2')
display(answer)

요일별로 categoryId의 빈도를 집계하여 피벗 테이블 형식으로 출력합니다.


Q6. view_count 대비 댓글 수가 가장 높은 영상 찾기

# view_count 대비 댓글 수 계산
target2 = df.loc[df.view_count != 0]
t = target2.copy()
t['ratio'] = (target2['comment_count'] / target2['view_count']).dropna()
result = t.sort_values(by='ratio', ascending=False).iloc[0].title
print(result)

이 코드는 view_count 대비 comment_count 비율을 계산하고, 가장 높은 영상을 출력합니다.

출력: 60분 동안 댓글이 달리지 않으면, 영상이 삭제됩니다. (챌린지)


Q7. view_count 대비 댓글 수가 가장 낮은 영상 찾기

ratio = (df['comment_count'] / df['view_count']).dropna().sort_values()
result = df.iloc[ratio[ratio != 0].index[0]].title
print(result)

댓글 비율이 가장 낮은 영상을 필터링하여 출력합니다.

출력: Join the BTS #PermissiontoDance Challenge only on YouTube #Shorts


Q8. like 대비 dislike 비율이 가장 낮은 영상 찾기

target = df.loc[(df.likes != 0) & (df.dislikes != 0)]
num = (target['dislikes'] / target['likes']).sort_values().index[0]
answer = df.iloc[num].title
print(answer)

likes 대비 dislikes 비율이 가장 낮은 영상을 출력합니다.

출력: [줌터뷰] 최초공개 사부작즈🐰🐶의 비공식 이름은 아이라인즈? 꿀조합 티키타카 가득한 NCT 127 도영&정우의 줌터뷰


Q9. 가장 많은 트렌드 영상을 제작한 채널 이름 찾기

answer = df.loc[df.channelId == df.channelId.value_counts().index[0]].channelTitle.unique()
print(answer)

트렌드 영상 제작 횟수가 가장 많은 채널명을 출력합니다.

출력: ['짤툰']


Q10. 20회 이상 인기 동영상 리스트에 포함된 동영상 수

answer = (df[['title', 'channelId']].value_counts() >= 20).sum()
print(answer)

titlechannelId를 기준으로, 20회 이상 리스트에 포함된 동영상 수를 출력합니다.

출력: 40


Q11. 각 video 데이터의 videoname별 데이터 개수 확인하기

video['ct'] = pd.to_datetime(video['ct'])
answer = video.videoname.value_counts()
print(answer)

videoname별 데이터 개수를 세고 출력합니다.

출력 예시:

공범 EP1    3492
공범 EP2    3204
공범 EP3    2568
...

Q12. video의 가장 최신 날짜별 viewcount 출력

answer = video.sort_values(['videoname', 'ct']).drop_duplicates('videoname', keep='last')[['viewcnt', 'videoname', 'ct']].reset_index(drop=True)
display(answer)

videoname별 최신 날짜와 그 날짜의 viewcount를 출력합니다.


Q13. 2021-10-03 이후 각 채널의 처음 기록된 구독자 수

channel.ct = pd.to_datetime(channel.ct)
target = channel[channel.ct >= pd.to_datetime('2021-10-03')].sort_values(['ct', 'channelname']).drop_duplicates('channelname')
answer = target[['channelname', 'subcnt']].reset_index(drop=True)
print(answer)

2021-10-03 이후 처음 기록된 각 채널의 구독자 수를 출력합니다.


Q14. 특정 기간 동안 구독자 수 증가량 계산

end = channel.loc[channel.ct.dt.strftime('%Y-%m-%d %H') == '2021-11-01 15']
start = channel.loc[channel.ct.dt.strftime('%Y-%m-%d %H') == '2021-10-03 03']

end_df = end[['channelname', 'subcnt']].reset_index(drop=True)
start_df = start[['channelname', 'subcnt']].reset_index(drop=True)

end_df.columns = ['channelname', 'end_sub']
start_df.columns = ['channelname', 'start_sub']

두 시점의 구독자 수 차이를 계산하여 구독자 증가량을 파악합니다.


Q15. 공범 EP1의 수집 간격이 비정상인 데이터 출력하기

문제 설명:공범 EP1의 비디오 데이터 중 수집 간격이 5분 이하 또는 20분 이상인 데이터의 시각을 출력합니다.

import datetime

# 공범 EP1 데이터 필터링 및 정렬
ep_one = video.loc[video.videoname.str.contains('1')].sort_values('ct').reset_index(drop=True)

# 간격이 5분 이하 또는 20분 이상인 데이터 확인
ep_one_filtered = ep_one[(ep_one.ct.diff(1) >= datetime.timedelta(minutes=20)) | \
                         (ep_one.ct.diff(1) <= datetime.timedelta(minutes=5))]

# 결과 출력
print(ep_one_filtered)

해설:

  • diff(1)은 현재 시점과 이전 시점의 시간 간격을 계산합니다.
  • datetime.timedelta(minutes=20)와 비교하여 간격이 기준을 초과하거나 미달하는 데이터를 필터링합니다.

Q16. 각 에피소드의 시작 날짜 추출하기

문제 설명:
각 에피소드의 시작 날짜를 추출하고, 에피소드 이름과 묶어 데이터프레임으로 구성합니다.

# 각 에피소드의 첫 번째 데이터 필터링
start_date = video.sort_values(['ct', 'videoname']).drop_duplicates('videoname')[['ct', 'videoname']]

# 날짜 컬럼 추가
start_date['date'] = start_date.ct.dt.date
answer = start_date[['date', 'videoname']]

# 결과 출력
print(answer)

해설:

  • sort_values로 시간 순 정렬 후 drop_duplicates를 사용해 각 에피소드의 첫 데이터를 선택합니다.
  • .dt.datedatetime 형식에서 날짜 부분만 추출합니다.

Q17. 공개된 날 21시의 viewcnt 데이터 출력

문제 설명:
공개된 날의 21시에 기록된 viewcnt, ct, videoname 데이터를 내림차순으로 정렬하여 출력합니다.

# 시간 정보 추가
video['time'] = video.ct.dt.hour

# 21시에 해당하는 데이터 필터링
data_21h = video.loc[video['time'] == 21]

# 각 에피소드별 21시 데이터 추출 및 정렬
answer = data_21h.sort_values(['videoname', 'ct']) \
                .drop_duplicates('videoname') \
                .sort_values('viewcnt', ascending=False)[['videoname', 'viewcnt', 'ct']] \
                .reset_index(drop=True)

# 결과 출력
print(answer)

해설:

  • dt.hour로 시간 정보를 추출하고, 21시에 해당하는 데이터를 필터링합니다.
  • 에피소드별로 중복되지 않도록 정리하고 viewcnt 기준으로 정렬합니다.

Q18. 가장 최근 데이터의 싫어요/좋아요 비율 계산하기

문제 설명:
각 에피소드의 가장 최근 데이터를 기준으로 dislikecnt / likecnt 비율을 계산하고, 이를 오름차순으로 정렬합니다.

# 가장 최근 데이터 추출
target = video.sort_values('ct').drop_duplicates('videoname', keep='last')

# 싫어요/좋아요 비율 계산
target['ratio'] = target['dislikecnt'] / target['likecnt']

# 결과 정렬 및 출력
answer = target.sort_values('ratio')[['videoname', 'ratio']].reset_index(drop=True)
print(answer)

해설:

  • drop_duplicates로 가장 최근 데이터를 선택합니다.
  • 싫어요/좋아요 비율을 계산한 후, 오름차순으로 정렬하여 결과를 확인합니다.

Q19. 특정 시간대 viewcnt 증가량 계산

문제 설명:
2021-11-01 00:00:00 ~ 15:00:00 사이에 각 에피소드의 viewcnt 증가량을 계산합니다.

# 시간 범위 설정
start = pd.to_datetime("2021-11-01 00:00:00")
end = pd.to_datetime("2021-11-01 15:00:00")

# 해당 시간 범위의 데이터 필터링
target = video.loc[(video['ct'] >= start) & (video['ct'] <= end)].reset_index(drop=True)

# 증가량 계산 함수 정의
def calculate_increase(x):
    return max(x) - min(x)

# 증가량 계산 및 결과 출력
answer = target[['videoname', 'viewcnt']].groupby('videoname').agg(calculate_increase)
print(answer)

해설:

  • 시간 범위에 해당하는 데이터를 필터링합니다.
  • 그룹별로 viewcnt의 최대값과 최소값 차이를 계산하여 증가량을 도출합니다.

Q20. 중복된 데이터의 시간대와 videoname 출력

문제 설명:
중복된 데이터의 시간대와 videoname 정보를 추출합니다.

# 중복 데이터 확인
duplicates = video[video.index.isin(set(video.index) - set(video.drop_duplicates().index))]

# 중복 데이터의 시간대와 videoname 출력
result = duplicates[['videoname', 'ct']]
print(result)

해설:

  • drop_duplicates로 중복을 제거한 후, 원본 데이터와 비교하여 중복된 데이터를 식별합니다.

  • 중복된 데이터에서 videonamect 정보를 출력합니다.
    정리:

  • 다양한 데이터 분석 문제를 해결하며 pandas의 기본기능과 활용법을 연습했습니다.

  • 실전 예제를 통해 데이터 정제, 계산, 정렬 및 조건부 필터링을 익혔습니다.

0개의 댓글