본문 바로가기

Coding/EDA

Google Play Store – Most Downloaded Android Apps

반응형

이거는 말 그대로 플레이스토어 앱 정보가 있는 데이터인데… 본인 아이폰 씁니다. 근데 왜 플레이스토어죠? 앱스토어 데이터가 없다.

 

참고로 전처리 할거 꽤 있으니까 잘 따라오십쇼.


전처리

가격 정상화

가격 정상화는 투트랙으로 이뤄질건데, 일단 앱 가격에 붙어있는 $를 다 빼고 float으로 만들어줄거다. 그리고 결측값도 채워줄건데, 결측값이 있는 앱들은 다 무료 앱이라 0으로 때울거다.

 

# 일단 저 달러부터 떼보시죠 
playstore_df['Price']
0       NaN
1       NaN
2       NaN
3       NaN
4       NaN
      ...  
82    $4.99
83    $3.49
84    $6.99
85    $4.99
86    $3.99
Name: Price, Length: 87, dtype: object

저기 가격 붙어있는거 옆에 달러를 다 떼줄겁니다. ㅇㅋ? ㅇㅇㅋ.

 

playstore_df['Price'] = playstore_df['Price'].str.replace('$', '', regex=False)
playstore_df['Price']
0      NaN
1      NaN
2      NaN
3      NaN
4      NaN
      ... 
82    4.99
83    3.49
84    6.99
85    4.99
86    3.99
Name: Price, Length: 87, dtype: object

그럼에도 아직 오브젝트인 이유는 일단 결측값이 있어서가 아닐까 하는 합리적인 의심을 해봅니다.

 

# 일단 가격이 결측값이 0인 모든 앱의 가격들이 다 무료인지 봅시다. 
free_index = playstore_df.query('Price.isna()').index

for idx in free_index:
    print(playstore_df['Type'].loc[idx])

0으로 때웁시다. 다 무료네.

 

playstore_df['Price'] = playstore_df['Price'].fillna(0) # 채우고 
playstore_df['Price'] = pd.to_numeric(playstore_df['Price']) # 바꾸면

playstore_df['Price'] # 정상화 끝

때운 다음 형변환도 해줘서 이제 float입니다.

 

날짜 형변환

# 날짜가 두개지요? 
# 난 저 리치드가 제출일인 줄 알았는데 일고보니 특정 다운로드 수에 도달한 날짜였음... 그래서 리치드가 퍼블리시드보다 뒤 시점입니다. 
playstore_df['Date_Reached'] = pd.to_datetime(playstore_df['Date_Reached'], errors='coerce')
playstore_df['Date_Published'] = pd.to_datetime(playstore_df['Date_Published'], errors='coerce')

에러나서 봤더니 언노운이 껴있더라고?

 

년도 추출

# 발매년도
playstore_df['Release_year'] = playstore_df['Date_Published'].dt.year
playstore_df['Release_year']

대체 NaT 껴있는거랑 플로트랑 뭔 상관인거임?

 

마일스톤 도달까지 걸린 일수

# 이걸로 되는겨? 
diff = playstore_df['Date_Reached'] - playstore_df['Date_Published']
playstore_df['To_reach'] = diff.dt.days

이거 데이터프레임에는 n days로 표기되는데 타입은 데이트타임임다.

 

설마 이상한거 없겠지

playstore_df.query('To_reach < 0')
App	Developer	Downloads	Date_Reached	Date_Published	Category	Pre_installed	Type	Price	Release_year	To_reach
7	Android Accessibility Suite	Google	10B+	2022-12-18	NaT	Accessibility tool	Yes	Free	0.00	NaN	-9223372036854775808
19	Google Hangouts	Google	5B-10B	2021-06-03	NaT	Communication	NaN	Free	0.00	NaN	-9223372036854775808
55	Duolingo	Duolingo Inc.	500M-1B	NaT	NaT	Games & education	No	Free	0.00	NaN	-9223372036854775808
78	Camera ZOOM FX Premium	androidslide	1M-5M	2012-03-19	NaT	Photo editor	No	Paid	4.99	NaN	-9223372036854775808

 

아뇨 있는데요? 

 

# 날립시다. 
playstore_df = playstore_df.dropna()
playstore_df

저 데이로 매겨야되는데 결측값 껴있으면 거시기하니까 날리자 걍.


오케이 렛츄고

마일스톤별 분석

특정 마일스톤별로 묶어서 한번 봅시다.

# 마일스톤별 그룹화 
playstore_df.groupby('Downloads').size()
Downloads
10B+       16
10M+        5
1B-5B      24
1M-5M       9
500M-1B    11
5B-10B     12
5M-10M      6
dtype: int64

얘는 전처리 감도 안오더라… 여기서 마일스톤 그룹별로는 어떤 앱이 가장 빨리 달성했을까?

 

가장 빨리 마일스톤을 달성한 앱

# 마일스톤별로 묶은 다음 최솟값의 인덱스를 추출 
min_idx = playstore_df.groupby('Downloads')['To_reach'].idxmin()

# 오케이 렛츠씨 
playstore_df.loc[min_idx]

와 게임이 두개나 있는데 내가 모르는 게임이야...

 

마일스톤 달성에 오래걸린 앱

# 마일스톤별로 묶은 다음 최솟값의 인덱스를 추출 
max_idx = playstore_df.groupby('Downloads')['To_reach'].idxmax()

# 오케이 렛츠씨 
playstore_df.loc[max_idx]

인별이 오래걸린건 좀 의외다. 구글번역기... 음... 사실 요즘 한국인들은 다 파파고 씁니다...

 

게임! 게임을 보자! 

game_df = playstore_df.query('Category.str.contains("Game")')
game_df

왜 쿼리에 저게 들어가냐고요? 카테고리가 게임, 어쩌고 게임 & 저쩌고 다 이난리라서요. 진짜 정규화 마려웠음.

 

# 마일스톤별로 묶은 다음 최솟값의 인덱스를 추출 
min_idx = game_df.groupby('Downloads')['To_reach'].idxmin()

# 오케이 렛츠씨 
game_df.loc[min_idx]

슈터가 세개지요…

 

# 마일스톤별로 묶은 다음 최솟값의 인덱스를 추출 
max_idx = game_df.groupby('Downloads')['To_reach'].idxmax()

# 오케이 렛츠씨 
game_df.loc[max_idx]

포고는 솔직히 느그언틱이 뻘짓만 덜했어도 좀 더 빨리 도달했을것같은데. 

 

마인크래프트나 로블록스나 다들 애들이 좋아하는 게임이간 한데, 마인크래프트는 '돈을 내고' 게임을 사야 하고 로블록스는 설치는 공짜고 인게임 안에서 뭘 사야 하는 구조다. 그럼 유료게임들이 다 마일스톤 달성이 오래 걸리냐 하면 그것도 아닌게, 위에 빨리 달성한 게임들에도 유료게임이 있어요. 게임이 오래 가려면 재미와 게임성도 중요하지만 운영을 X같이 하면 안됩니다.

 

무료앱

# 마일스톤별로 묶은 다음 최솟값의 인덱스를 추출 
min_idx = free_df.groupby('Downloads')['To_reach'].idxmin()

# 오케이 렛츠씨 
free_df.loc[min_idx]

일단 유튜브 뮤직은 한번도 쓴적 없지만 가끔 Flo는 쓴다. 근데 이것도 요금제 무료로 주는거 있어서 쓰는거지 보통은 잘 안 씀. 나는 음원 다운로드해서 폰에 넣고다닌다. 애초에 내가 듣고 다니는 노래 중에 특정 음원사이트에는 수록 안 되는 곡도 있고(특히 멜론) 대부분 요금이 구독제거든.. 내가 구독하는건 포홈 박스(1년에 2만원)랑 닌스온, 드롭박스, 아이클라우드가 다다.

 

그리고 유튜브는 이것들 광고 꼬라지가 X같아서 구독하기 싫음. 막말로 얘네 돈만 많이 주면 나도 광고해줄걸?

 

# 마일스톤별로 묶은 다음 최솟값의 인덱스를 추출 
max_idx = free_df.groupby('Downloads')['To_reach'].idxmax()

# 오케이 렛츠씨 
free_df.loc[max_idx]

구글번역기... 음... 내 중고딩 시절에는 번역이 발퀄이라 안 썼고 요즘은 파파고나 DeepL이 잘 되어있어서 안씁니다...

 

유료앱

# 마일스톤별로 묶은 다음 최솟값의 인덱스를 추출 
min_idx = paid_df.groupby('Downloads')['To_reach'].idxmin()

# 오케이 렛츠씨 
paid_df.loc[min_idx]

얘네들 뭐 하는 게임임? 한번도 못본거같은데..

 

# 마일스톤별로 묶은 다음 최댓값의 인덱스를 추출 
max_idx = paid_df.groupby('Downloads')['To_reach'].idxmax()

# 오케이 렛츠씨 
paid_df.loc[max_idx]

문제는 얘들도 뭐 하는 애들인지 모르겠음.

 

년도별로 보기

2010~2020

참고로 2010년도 이전 앱도 있긴 있습니다. 근데 내가 갤럭시 A를 본 게 2010년인데? 뭔 경우냐 이건?

 

year_min_idx = playstore_df.query('2010 <= Release_year < 2021').groupby(['Release_year'])['To_reach'].idxmin()
playstore_df.loc[year_min_idx]

음... 스타듀밸리는 그럴만 했지. 후르츠 닌자도 예전에 스마트폰이나 어른패드에서 많이 했던 게임 중 하나다. 일단 저 게임은 룰이 대단히 간단한데, 과일만 싹둑해야 합니다. 근데 그 과일만 싹둑하는 작업이 은근 어려운게 포인트임. 염소 시뮬레이터는... 그래요.. 걔들은 약 빨고 게임을 만들었어...

 

year_max_idx = playstore_df.query('2010 <= Release_year < 2021').groupby(['Release_year'])['To_reach'].idxmax()
playstore_df.loc[year_max_idx]

우리 그 클래스챗이 따로 있는데 거기서 가끔 문제가 터집니다. 마이크가 뻑나서 본의아니게 다리를 얻고 목소리를 잃은 인어공주가 되기도 하고, 소리가 안들려서 베토벤이 이 상황에서 작곡을 했구나를 깨닫기도 함. 그럴때 대안으로 쓰는게 구글미트예요. 많이 쓰임.

 

스타듀밸리는… 2019년에 설마 저거 하나 들어간거 아니지?

 

2021~

2021년 이후는 코드 올리고 자시고 할 것도 없는게, 이게 답니다. 데이터 원본 행 수가 좀 빈약함…

 

모스트 다운로드 오브 구글 앱

google_df = playstore_df.query('Developer.str.contains("Google") and Downloads == "10B+"')
google_df

B가 10억이니까 쟤들은 최소 100억번 이상 다운로드 됐다는 얘기가 되겠죠…

 

google_df_s = google_df.sort_values('To_reach', ascending=False)
sns.barplot(google_df_s, x = 'App', y = 'To_reach', hue = 'App', palette='viridis')
plt.title('To reach for milestone: Google apps')
plt.xlabel('App')
plt.xticks(rotation = 45)
plt.ylabel('To Reach (days)')
plt.show()

저 안드로이드 스위치 뭐 하는 앱인지 아시는 분은 제보 바랍니다.

 

모스트 다운로드 오브 게임

most_game_df = playstore_df.query('Category.str.contains("Games") and Downloads.str.contains("B")')
most_game_df = most_game_df.sort_values(['Downloads','To_reach'], ascending = [True, False])
sns.barplot(most_game_df, x = 'App', y = 'To_reach', hue = 'Downloads', palette='viridis')
plt.title('To reach for milestone: Games')
plt.xlabel('App')
plt.xticks(rotation = 45)
plt.ylabel('To Reach (days)')
plt.show()

내 언젠가 저 세팅도 화이트그리드로 싹 바꿀것이다…

 

근데 로블록스가 애들한테 인기있는 게임 아니었나? 생각보다 도달하는데 오래걸렸다?

반응형

'Coding > EDA' 카테고리의 다른 글

Red Wine Quality  (0) 2026.03.13
Palmer Archipelago (Antarctica) penguin data  (0) 2026.03.11
얘! clinvar도 EDA가 된단다! (3)  (0) 2026.02.18
얘! clinvar도 EDA가 된단다! (2)  (0) 2026.02.17
얘! clinvar도 EDA가 된단다! (1)  (0) 2026.02.15