前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Day04| 第四期-谷歌应用商店的App分析

Day04| 第四期-谷歌应用商店的App分析

作者头像
DataScience
发布2020-07-14 16:00:11
1.4K0
发布2020-07-14 16:00:11
举报
文章被收录于专栏:A2DataA2Data

01 前言

我们每天都在使用从手机应用商店里下载的App,有没有想过什么样的App是最受欢迎的呢?一个最直接的方法,就是前往应用商店,对App的属性进行分析,得出受欢迎的应用的特点,可以辅助新的App开发设计或是掌握当下人们使用App的流行趋势。

Google Play Store 是在国外手机用户下载安卓应用程序的商店,今天的案例是对商店中app的统计数据进行分析,重点掌握业务分析中数据清洗的方法。

公号回复:DT17 获取数据 googleplaystore.csv

02 数据观察

如图所示,App的属性信息在网页可以轻松获取,此份数据也是从网络上爬取下来的。

观察数据,如下图所示,第一行是列名,含有App程序名称,Category类别,Rating评分,Reviews评论数,Size程序大小,Installs安装数量等等,总共有1w条数据。了解数据过后,接下来用Python读取csv文件。

import numpy as np
import pandas as pd
df = pd.read_csv('./googleplaystore.csv',usecols=(0,1,2,3,4,5,6)) # usecols取7列数据
df.head()  # 观察前几行数据 了解字段含义
df.describe() # 只有rating列有描述统计 说明其他列的数据类型是字符串

Rating

count

9367.000000

mean

4.193338

std

0.537431

min

1.000000

25%

4.000000

50%

4.300000

75%

4.500000

max

19.000000

df.count() # 统计每一列的行数 发现Rating行数少一千多行,Type少一行
# 有重复、缺失和异常的数据,接下来需要对数据进行清洗
App         10841
Category    10841
Rating       9367
Reviews     10841
Size        10841
Installs    10841
Type        10840
dtype:  int64

03 数据清洗

# 数据清洗,一列一列地进行分析,判断是否有重复值和缺失值以及异常值
# App列清洗,由于Rating 评论数数小于App数,猜测App有重复值
pd.unique(df['App']).size 
9660
# 发现App的unique行数是9660,说明有重复值,但是在第一列先不进行去重,因为可能有App名重名的情况,需要结合其他列判断
# Category 列处理
df['Category'].value_counts(dropna=False) # 空值也统计
FAMILY                 1972
GAME                   1144
TOOLS                   843
MEDICAL                 463
BUSINESS                460
PRODUCTIVITY            424
PERSONALIZATION         392
COMMUNICATION           387
SPORTS                  384
LIFESTYLE               382
FINANCE                 366
HEALTH_AND_FITNESS      341
PHOTOGRAPHY             335
SOCIAL                  295
NEWS_AND_MAGAZINES      283
SHOPPING                260
TRAVEL_AND_LOCAL        258
DATING                  234
BOOKS_AND_REFERENCE     231
VIDEO_PLAYERS           175
EDUCATION               156
ENTERTAINMENT           149
MAPS_AND_NAVIGATION     137
FOOD_AND_DRINK          127
HOUSE_AND_HOME           88
LIBRARIES_AND_DEMO       85
AUTO_AND_VEHICLES        85
WEATHER                  82
ART_AND_DESIGN           65
EVENTS                   64
COMICS                   60
PARENTING                60
BEAUTY                   53
1.9                       1
Name: Category, dtype: int64
# 发现类别名,没有空值;
# 末尾一行的类别名为1.9,可能是异常值,挑选出来进行观察
df[df['Category'] == '1.9']
# Category为1.9 Rating为19(rating一般为1-5分)Size为1000+(应该写为xxM) Type应该是Free
# 判断这一行,缺失了category,应该把1.9往后的数据往右移动一列,实际操作中可以在网页页面上查找到类别补充上去
# 由于补充信息并移动列操作比较繁琐,数据有一万多行,直接删除这一行影响不大
df.drop(index=10472, inplace=True) 
# Rating列处理
df['Rating'].value_counts(dropna=False)
NaN    1474
4.4    1109
4.3    1076
4.5    1038
4.2     952
4.6     823
4.1     708
4.0     568
4.7     499
3.9     386
3.8     303
5.0     274
3.7     239
4.8     234
3.6     174
3.5     163
3.4     128
3.3     102
4.9      87
3.0      83
3.1      69
3.2      64
2.9      45
2.8      42
2.7      25
2.6      25
2.5      21
2.3      20
2.4      19
1.0      16
2.2      14
1.9      13
2.0      12
1.7       8
1.8       8
2.1       8
1.6       4
1.5       3
1.4       3
1.2       1
Name: Rating, dtype: int64
# Rating的分布在[0-5]之间,数据没有问题,但是NaN空值有1474个,影响较大,需要进行处理,在这里给NaN赋上平均值;
df['Rating'].fillna(value=df['Rating'].mean(), inplace=True) 
# fillna()函数,对NaN进行赋值
df['Rating'].value_counts(dropna=False)
4.191757    1474
4.400000    1109
4.300000    1076
4.500000    1038
4.200000     952
4.600000     823
4.100000     708
4.000000     568
4.700000     499
3.900000     386
3.800000     303
5.000000     274
3.700000     239
4.800000     234
3.600000     174
3.500000     163
3.400000     128
3.300000     102
4.900000      87
3.000000      83
3.100000      69
3.200000      64
2.900000      45
2.800000      42
2.700000      25
2.600000      25
2.500000      21
2.300000      20
2.400000      19
1.000000      16
2.200000      14
1.900000      13
2.000000      12
1.800000       8
1.700000       8
2.100000       8
1.600000       4
1.500000       3
1.400000       3
1.200000       1
Name: Rating, dtype: int64
# Reviews列处理
df['Reviews'].value_counts(dropna=False)
0         596
1         272
2         214
3         175
4         137
5         108
6          97
7          90
8          74
9          65
10         64
12         60
11         52
13         49
17         48
19         41
14         41
16         35
21         35
20         35
15         31
30         30
24         30
25         30
38         29
18         27
22         26
23         25
27         25
33         24
         ...
127229      1
2159        1
157264      1
6826        1
21262       1
37607       1
71269       1
67071       1
24215       1
63624       1
10753       1
159455      1
72596       1
8191        1
258556      1
10672       1
454412      1
56065       1
42329       1
84114       1
71432       1
815893      1
654419      1
9562        1
580         1
2976        1
18478       1
73821       1
1740        1
354         1
Name: Reviews, Length: 6001, dtype: int64
# Reviews 每个app评论数的分布非常广,评论为0的情况最多,有596个
# 在开头使用describe函数,并没有出现reviews列的统计信息,这一列中的数据可能含有字符串,数据格式可能不对
df['Reviews'].str.isnumeric().sum()
10840
# 10840个数值型数据,没有字符串数据
# 之前在category列中删除一行后,说明reviews列剩下的都是数值型的数据
# 也可以进行验证是否存在非数值型数据
df[-df['Reviews'].str.isnumeric()]
# 发现都是数值型数据,再次使用describe函数,是否出现reviews的列描述
df.describe() # 没有出现reviews列的统计信息,可能是数字格式不对
# 统一将数据格式转换
df['Reviews'] = df['Reviews'].astype('i8') # int8
df.describe()
# 最大的评论数有7.815831e+07 7.8乘以10的7次方,也就是百万次,最小是0,没有出现负值,数据合理
# Size的清洗处理
df['Size'].value_counts(dropna=False)
Varies with device    1695
11M                    198
12M                    196
14M                    194
13M                    191
15M                    184
17M                    160
19M                    154
26M                    149
16M                    149
25M                    143
20M                    139
21M                    138
24M                    136
10M                    136
18M                    133
23M                    117
22M                    114
29M                    103
27M                     97
28M                     95
30M                     84
33M                     79
3.3M                    77
37M                     76
35M                     72
31M                     70
2.9M                    69
2.3M                    68
2.5M                    68
                      ...
245k                     1
860k                     1
67k                      1
942k                     1
629k                     1
940k                     1
208k                     1
787k                     1
785k                     1
14k                      1
921k                     1
116k                     1
234k                     1
378k                     1
865k                     1
226k                     1
122k                     1
222k                     1
400k                     1
191k                     1
549k                     1
642k                     1
209k                     1
778k                     1
540k                     1
240k                     1
663k                     1
220k                     1
11k                      1
485k                     1
Name: Size, Length: 461, dtype: int64
# Varies with device    1695 ,size大小不确定,因此不方便分析,同使用均值代替
# 计算时,Size带有M和K的单位,不方便计算,因此需要去掉
df['Size'] = df['Size'].str.replace('M','e+6')
df['Size'] = df['Size'].str.replace('k','e+3')
# 尝试转换数据类型,此时转换报错,还有字符串
# df['Size'].astype('f8')
# 定义一个字符串判断判断数据是否可以转换
def is_convertable(v):
    try:
        float(v)
        return True
    except ValueError:
        return False

df['Size'].apply(is_convertable)
# 查看不能转换的字符串分布 即含有false的项
temp = df['Size'].apply(is_convertable)
df['Size'][-temp].value_counts()
# 转换剩下的字符串
df['Size'] = df['Size'].str.replace('Varies with device', '0')
# 再次确认是否有未转换的字符串
temp = df['Size'].apply(is_convertable)
df['Size'][-temp].value_counts()
# 转换类型
# e+5 类似科学计数法格式的数据使用astype直接转为int有问题,转成int,可以先转成f8,再转i8
df['Size'] = df['Size'].astype('f8').astype('i8')
# 将Size为0的填充为平均数
df['Size'].replace(0, df['Size'].mean(), inplace=True)
df.describe()
# Installs数据清洗
# 查看分布,数值中带有逗号和加号
df['Installs'].value_counts()
1,000,000+        1579
10,000,000+       1252
100,000+          1169
10,000+           1054
1,000+             907
5,000,000+         752
100+               719
500,000+           539
50,000+            479
5,000+             477
100,000,000+       409
10+                386
500+               330
50,000,000+        289
50+                205
5+                  82
500,000,000+        72
1+                  67
1,000,000,000+      58
0+                  14
0                    1
Name: Installs, dtype: int64
# 替换 加号和逗号,以方便数据分析
df['Installs'] = df['Installs'].str.replace('+', '')
df['Installs'] = df['Installs'].str.replace(',', '')
# 转换类型
df['Installs'] = df['Installs'].astype('i8')
df.describe()
# Type处理
df['Type'].value_counts(dropna=False)
Free    10039
Paid      800
NaN         1
Name: Type, dtype: int64
# 有一行是NaN,最简单的做法 需要找出此行所在index并删除
df[df['Type'].isnull()]
# 删除这条数据
df.drop(index=9148, inplace=True)
# 最后其他列都清洗完毕后,对App去重,保证了数据行数的一致
df.drop_duplicates('App',inplace = True)
df.count()
App         9658
Category    9658
Rating      9658
Reviews     9658
Size        9658
Installs    9658
Type        9658
dtype: int64

04 数维度分析和相关性分析

# 以上数据清洗完成,接下来对每列进行分析
# 整体情况
df.describe()
# 选择维度进行分析

# 以Category类别为维度,分析哪些类别的App的最受欢迎
# 类别的个数
df.Category.unique().size
33 # 个类别
# 每个类别的App数量,排序,可以得出哪些分类的app最受开发者欢迎
df.groupby('Category').count().sort_values('App', ascending=False)
# 类别的安装量排序:娱乐社交类最被用户所需要
df.groupby('Category').mean().sort_values('Installs', ascending=False)
# 类别的评论数据:社交游戏视频评论多
df.groupby('Category').mean().sort_values('Reviews', ascending=False)
# 类别的评分数据:教育类评分最高
df.groupby('Category').mean().sort_values('Rating', ascending=False)
# 以Type (免费还是收费)来分析
df.groupby('Type').count()
# 只有两个类型,且数据量差别很大,没必要继续对比
df.groupby('Type').sum().sort_values('Installs', ascending=False)
# Category和Type一起分析
df.groupby(['Type', 'Category']).mean().sort_values('Reviews', ascending=False)
# 评论安装比
# 收费的app评论比率更高
g = df.groupby(['Type', 'Category']).mean()
(g['Reviews'] / g['Installs']).sort_values(ascending=False)
# 相关性:
#评论数和安装数强相关,其他的连0.1都不到,可以认为是不相关的(0.5以上可以认为是相关的,0.3以上可以认为是弱相关)
df.corr()

05 写在后面

我们对数据清洗的策略是按列进行分析是否有重复值,异常值和缺失值。如果某一列的数据去重后,少了一些行数,这可能并不是真的重复,会有出现重名的情况,因而不要盲目的将重复的数据删除,需要结合其他列进行判断。此外,从网页爬取的数据中,每列中的数据可能出现多种格式,为方便数值型数据的计算,还需要进行格式转换,并使用describe()验证。

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2020-07-09,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 DataScience 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
文件存储
文件存储(Cloud File Storage,CFS)为您提供安全可靠、可扩展的共享文件存储服务。文件存储可与腾讯云服务器、容器服务、批量计算等服务搭配使用,为多个计算节点提供容量和性能可弹性扩展的高性能共享存储。腾讯云文件存储的管理界面简单、易使用,可实现对现有应用的无缝集成;按实际用量付费,为您节约成本,简化 IT 运维工作。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档