Python广告数据挖掘与分析实战
上QQ阅读APP看书,第一时间看更新

3.2.6 广告缺失值处理

数据缺失在数据分析工作中是普遍存在的,而造成数据缺失的原因又是多种多样的,有的是因为数据无法获取或者获取数据的代价太大,有的是因为信息采集前期被遗漏或者设备故障问题导致数据丢失,还有的可能是因为数据不可用而舍弃导致的缺失。

按缺失的情况,我们一般将数据缺失分为完全随机缺失、随机缺失和完全非随机缺失。它们的具体定义如下。

1)完全随机缺失:数据的缺失是完全随机的,与其他变量无关。

2)随机缺失:该类数据的缺失依赖于其他变量,与所观察的变量有关,与未观察的变量无关。

3)完全非随机缺失:数据的缺失与变量自身的取值有关。

所以缺失值的处理要具体问题具体分析。在广告行业中,数据的缺失主要是因为无法获取数据导致的。缺失值的处理方法主要包括三种:不处理、删除缺失数据、填充缺失值。只有当我们对数据进行删除或者填充操作会对当前分析结果带来影响,或者我们明确知道该缺失数据对分析结果完全不会有影响时,我们才会对缺失值进行不处理操作。除此之外,我们一般都会对缺失数据进行相应的处理,而删除缺失数据和填充缺失值是比较常用的方法。Pandas提供了一些常用的数据缺失值处理方法,使得数据缺失值的处理简单高效了。

在Pandas的数据对象中一般用NaN表示缺失值,比如前面我们在进行数据拼接时就出现了因为左右两个表部分数据拼接不上而导致数据缺失的情况。在Pandas中我们通常使用isnull方法来获取缺失值的位置:


In [3]: df = pd.DataFrame({"ID":[1,2,np.NaN,4,5],
   ...:                  "Name":['A',np.NaN,np.NaN,"D","E"],
   ...                   "No":[100,101,102,103,105]})

In [4]: df.isnull()
Out[4]:
      ID   Name     No
0  False  False  False
1  False   True  False
2   True   True  False
3  False  False  False
4  False  False  False

也可以在isnull方法后使用聚合函数来进行汇总,以便后续观察字段的整体缺失情况:


In [5]: df.isnull().mean()
Out[5]:
ID      0.2
Name    0.4
No      0.0
dtype: float64

从以上结果可以看出,ID和Name字段的缺失值比例分别为0.2和0.4。

还可以使用notnull方法来获取非缺失值的位置:


In [6]: df.notnull()
Out[6]:
      ID   Name    No
0   True   True  True
1   True  False  True
2  False  False  True
3   True   True  True
4   True   True  True

可以看到,返回的结果刚好与isnull方法相反。

前面我们介绍了如何通过isnull/notnull方法来判断缺失值的位置,从而快速找出缺失值,下面将分别介绍在广告数据分析中常用的两种缺失值处理方法:删除缺失值和填充缺失值。

(1)删除缺失值

在Pandas中,通常使用dropna方法删除缺失数据:


In [7]: df.dropna()
Out[7]:
    ID Name   No
0  1.0    A  100
3  4.0    D  103
4  5.0    E  105

可以发现,dropna方法删除了所有含有缺失值的行。在上面的例子中,在删除缺失值后只保留了第1、4、5行的数据。但在实际中往往只需要删除全为缺失值的行,这里只需要修改参数how=‘all’即可:


In [8]: df.dropna(how = 'all')
Out[8]:
    ID Name   No
0  1.0    A  100
1  2.0  NaN  101
2  NaN  NaN  102
3  4.0    D  103
4  5.0    E  105

通过dropna方法我们还可以删除含缺失值的列:


In [9]: df.dropna(axis=1)
Out[9]:
    No
0  100
1  101
2  102
3  103
4  105

(2)填充缺失值

通过fillna方法我们可以将缺失值填充为任何我们想要的值,如下所示:


In [10]: df.fillna('miss')
Out[10]:
     ID  Name   No
0     1     A  100
1     2  miss  101
2  miss  miss  102
3     4     D  103
4     5     E  105

在以上情况下所有缺失值都会替换为miss,如果想在不同的列中填充不同的值,可以传入一个字典,字典的键指定需要填充的列名,字典的值指定需要填充的值,如下所示:


In [11]: df.fillna({'ID':3,"Name":'miss'})
Out[11]:
    ID  Name   No
0  1.0     A  100
1  2.0  miss  101
2  3.0  miss  102
3  4.0     D  103
4  5.0     E  105

在广告数据分析中,我们也经常采用列的平均值(mean)、中位数(median)或者众数(mode)来填充缺失值。这样做的好处是可以尽量减少噪声对整体数据的影响。


In [12]: df.loc[4,'ID'] = np.NaN

In [13]: df
Out[13]:
    ID Name   No
0  1.0    A  100
1  2.0  NaN  101
2  NaN  NaN  102
3  4.0    D  103
4  NaN    E  105

In [14]: df.fillna(df.mean())
Out[14]:
         ID Name   No
0  1.000000    A  100
1  2.000000  NaN  101
2  2.333333  NaN  102
3  4.000000    D  103
4  2.333333    E  105

因为均值填充只对连续变量有效,所以Name列的缺失值会被忽略。如果我们想对离散变量也进行相应的缺失值填充,可以有针对性地单独指定需要填充的值,类似前面的miss填充,这里不再赘述。