龙空技术网

数据缺失、混乱要怎么搞?教你用Python实现特征规范化、标准化

机智的格子间生活 338

前言:

现在我们对“python数据标准化”大体比较关切,朋友们都想要知道一些“python数据标准化”的相关知识。那么小编也在网上网罗了一些对于“python数据标准化””的相关文章,希望朋友们能喜欢,我们一起来学习一下吧!

导读:数据工作者经常会遇到各种状况,比如你收集到的数据并不像你期待的那样完整、干净。此前我们讲解了用OpenRefine搞定数据清洗,本文进一步探讨用pandas和NumPy插补缺失数据并将数据规范化、标准化。

作者:托马兹·卓巴斯(Tomasz Drabas)

如需转载请联系华章科技

本文将使用一个数据集,包含985项真实的房产交易。这些交易是连续5天内在Sacramento发生的。数据下载自:

数据已转成多种格式,放在GitHub代码库的Data/Chapter01文件夹中。

插补缺失值

数据的收集工作很棘手。收集工具坏了,调查问卷上某些问题人们不想回答,或者文件被损坏了;这些还只是数据集可能不全的一小部分原因。如果想使用这个数据集,我们有两个选择:忽略缺失的数据,或者用一些值替代。

1. 准备

要实践本技巧,你要先装好pandas模块。

2. 怎么做

csv_read DataFrame可供使用。要插补缺失值,你只需要使用下面的代码(data_imput.py文件):

# 估算平均数以替代空值csv_read['price_mean'] = csv_read['price'] \.fillna(csv_read.groupby('zip')['price'].transform('mean'))

3. 原理

pandas的.fillna(...)方法帮我们处理了所有重活。这是DataFrame对象的一个方法,将要估算的值作为唯一必须传入的参数。

查阅pandas文档中.fillna(...)的部分,了解可传入的其他参数。文档位于:

在我们的处理过程中,我们假设每个邮编可能会有不同的均价。这就是我们用.groupby(...)方法对数据分组的原因。房产的价格重度依赖于房间的数目,这个推论也是成立的;如果我们的数据集更大,我们还能考虑beds这个变量。

.groupby(...)方法返回一个GroupBy对象。其.transform(...)方法高效地对邮编分组,在我们的例子中,分组的依据是各邮编价格数据的平均数。

现在,.fillna(...)方法简单地用这个平均数替代缺失的观测数据即可。

4. 更多

插补数据不是填补缺失值的唯一方法。数据对称分布且没有异常值时,才会返回一个合理的值;如果分布比较偏,平均值是有偏差的。衡量集中趋势更好的维度是中位数。我们前面的例子只需要改一个小地方:

# 估算中位数以替代空值csv_read['price_median'] = csv_read['price'] \.fillna(csv_read.groupby('zip')['price'].transform('median'))
02 将特征规范化、标准化

为了提高计算效率,我们将特征规范化(或标准化),这样不会超出计算机的限制。探索模型中变量之间的相互作用时也建议这么处理。

计算机是有限制的:整型值是有上限的(尽管目前在64位机器上这不是个问题),浮点型的精确度也有上限。

数据规范化是让所有的值落在0到1的范围内(闭区间)。数据标准化是移动其分布,使得数据的平均数是0、标准差是1。

1. 准备

要实践本技巧,你要先装好pandas模块。

其他没有什么要准备的了。

2. 怎么做

要实现规范化与标准化,我们定义了两个辅助函数(data_standardize.py文件):

def normalize(col):'''规范化'''return (col - col.min()) / (col.max() - col.min())def standardize(col):'''标准化'''return (col - col.mean()) / col.std()

3. 原理

要规范化数据,即让每个值都落在0和1之间,我们减去数据的最小值,并除以样本的范围。统计学上的范围指的是最大值与最小值的差。normalize(...)方法就是做的前面描述的工作:对数据的集合,减去最小值,除以范围。

标准化的过程类似:减去平均数,除以样本的标准差。这样,处理后的数据,平均数为0而标准差为1。standardize(...)方法做了这些处理:

csv_read['n_price_mean'] = normalize(csv_read['price_mean'])csv_read['s_price_mean'] = standardize(csv_read['price_mean'])
03 分级数据

当我们想查看数据分布的形状,或将数据转换为有序的形式时,数据分级就派上用场了。

1. 准备

要实践本技巧,你要先装好pandas和NumPy模块。

2. 怎么做

可以用下面的代码(data_binning.py文件)对数据分级(比如处理成直方图):

# 根据线性划分的价格的范围,创建价格的容器bins = np.linspace(csv_read['price_mean'].min(),csv_read['price_mean'].max(),6)# 将容器应用到数据上csv_read['b_price'] = np.digitize(csv_read['price_mean'],bins)

3. 原理

第一步是创建容器。对于价格数据(缺失值用估算的平均数填补),我们创建了六个容器,在最小值和最大值之间均匀分配。.linspace(...)方法做了这点工作:创建长度为6的NumPy数组,其中每个元素比前一个大固定的差值。比如,.linspace(0, 6, 6)生成数组[0., 1.2, 2.4, 3.6, 4.8, 6.]。

NumPy对线性代数来说是个强大的数字处理库。可轻松处理大型数组和矩阵,还提供了极其丰富的函数操作数据。想了解更多,可访问:

.digitize(...)方法对指定列中的每个值,都返回所属的容器索引。第一个参数是要分级的列,第二个参数是容器的数组。

使用DataFrame的.value_counts()得到每个容器中的记录计数,counts_b = csv_read['b_price'].value_counts()。

4. 更多

有时候我们不会用均匀间隔的值,我们会让每个桶中拥有相同的数目。要达成这个目标,我们可以使用分位数。

分位数与百分位数有紧密的联系。区别在于百分位数返回的是给定百分数的值,而分位数返回的是给定分位点的值。想了解更多,可访问:

我们想把列拆成十分位数,即10个(差不多)相等的容器。要做到这点,我们可以使用下面的代码(你可以一眼看出其和之前方法的相似之处):

# 根据十分位数创建容器decile = csv_read['price_mean'].quantile(np.linspace(0, 1, 11))# 将容器应用到数据上csv_read['p_price'] = np.digitize(csv_read['price_mean'],decile)

.quantile(...)方法可以传一个(0到1之间的)数字,来表明要返回的分位数(例如,0.5是中位数,0.25和0.75是上下四分位数)。它也可以传入一个分位的列表,返回相应的值的数组。.linspace(0, 1, 11)方法会生成这个数组:

[ 0., 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.]

所以,.quantile(...)方法会以price_mean列的最小值开始,直到最大值,返回十分位数的列表。

04 编码分类变量

为数据的探索阶段准备的最后一步就是分类变量了。有些软件包在背后做了这个工作,但最好还是理解这步处理的时机与做法。

统计模型只能接受有序的数据。分类变量(有时根据上下文可表示为数字)不能直接在模型中使用。要使用它们,我们要先进行编码,也就是给它们一个唯一的数字编号。这解释了什么时候做。至于如何做—应用下述技巧即可。

1. 准备

要实践本技巧,你要先装好pandas模块。

其他没有什么要准备的了。

2. 怎么做

pandas又提供了一个方法,帮我们做完所有事(data_dummy_code.py文件):

# 根据房产类型处理的简单代码csv_read = pd.get_dummies(csv_read,prefix='d',columns=['type'])

3. 原理

.get_dummies(...)方法将分类变量转换为简单的变量。比如,考虑一个变量,以三种水平中的某一种作为值:

1 One2 Two3 Three

需要用三列进行编码:

1 One 1 0 02 Two 0 1 03 Three 0 0 1

有时可用两列。如果有一个水平等效于null的话,我们可以这样做:

1 One 1 0 2 Two 0 1 3 Three 0 0 

.get_dummies(...)方法的第一个参数是DataFrame对象。columns参数指定了代码要处理的DataFrame的列(或某些列,因为可以传入列表)。通过指定前缀,我们告诉方法生成的列名以d打头;本例中生成的列会叫d_Condo。下划线是默认的,可以通过指定prefix_sep参数更改。

.get_dummies(...)方法的完整参数列表,参见:

关于作者:托马兹·卓巴斯(Tomasz Drabas),微软数据科学家,致力于解决高维特征空间的问题。他有超过13年的数据分析和数据科学经验:在欧洲、澳大利亚和北美洲三大洲期间,工作领域遍及高新技术、航空、电信、金融和咨询。

本文摘编自《数据分析实战》,经出版方授权发布。

延伸阅读《数据分析实战》

推荐语:通过大量的现实案例,详细讲解数据分析相关的各种方法。

标签: #python数据标准化