数据规范化的代码实现(Python)

前言

本文通过Python实现三种常见的数据规范化方法,包括最小-最大规范化,零-均值规范化,小数定标规范化。

最小-最大规范化(Min-max): x ∗ = x − m i n m a x − m i n x^*=\frac{x-min}{max-min} x=maxminxmin,min表示最小值,max表示最大值

零-均值规范化(Z-score): x ∗ = x − x ˉ σ x^*=\frac{x-\bar{x}}{\sigma} x=σxxˉ x ˉ \bar{x} xˉ表示均值, σ \sigma σ表示方差

小数定标规范化: x ∗ = x 1 0 k x^*=\frac{x}{10^k} x=10kx,k表示小数点移动的位数

方法一:通过pandas包实现

实现代码

import numpy as np
import pandas as pd

# 原始数据,每一行表示一个样本,每一列表示一个特征
raw_data = np.array([       
    [78, 521, 602, 2862],
    [144, -600, -521, 2245],
    [95, -457, 468, -1283],
    [69, 596, 695, 1054],
    [190, 527, 691, 2051],
    [101, 403, 470, 2487]
    ])

data = pd.DataFrame(raw_data)

# 最小-最大规范化
min_max = (data-data.min()) / (data.max()-data.min())

# 零-均值规范化       
z_score = (data-data.mean()) / data.std()

# 小数定标规范化     
decimal_scaling = data / 10**np.ceil(np.log10(data.abs().max()))

# 打印结果
print(min_max)
print(z_score)
print(decimal_scaling)

输出结果

min_max
Out[26]: 
          0         1         2         3
0  0.074380  0.937291  0.923520  1.000000
1  0.619835  0.000000  0.000000  0.851146
2  0.214876  0.119565  0.813322  0.000000
3  0.000000  1.000000  1.000000  0.563812
4  1.000000  0.942308  0.996711  0.804343
5  0.264463  0.838629  0.814967  0.909530

z_score
Out[27]: 
          0         1         2         3
0 -0.759445  0.656051  0.434805  0.848567
1  0.679503 -1.409773 -1.992464  0.443540
2 -0.388807 -1.146247  0.145175 -1.872406
3 -0.955665  0.794264  0.635816 -0.338289
4  1.682407  0.667108  0.627171  0.316189
5 -0.257993  0.438596  0.149498  0.602400

decimal_scaling
Out[28]: 
       0      1      2       3
0  0.078  0.521  0.602  0.2862
1  0.144 -0.600 -0.521  0.2245
2  0.095 -0.457  0.468 -0.1283
3  0.069  0.596  0.695  0.1054
4  0.190  0.527  0.691  0.2051
5  0.101  0.403  0.470  0.2487

方法二:通过scikit-learn包实现

实现代码

from sklearn import preprocessing
import numpy as np

# 原始数据,每一行表示一个样本,每一列表示一个特征
raw_data = np.array([       
    [78, 521, 602, 2862],
    [144, -600, -521, 2245],
    [95, -457, 468, -1283],
    [69, 596, 695, 1054],
    [190, 527, 691, 2051],
    [101, 403, 470, 2487]
    ])

# 最小-最大规范化
# 将数据进行[0,1]规范化;最小最大值区间可以指定,默认是映射到[0,1]区间
min_max_scaler = preprocessing.MinMaxScaler()
min_max = min_max_scaler.fit_transform(raw_data)


# 零-均值规范化
z_score = preprocessing.scale(raw_data)

# 小数定标规范化
# 主要是通过NumPy库来计算小数点的位数
k = np.ceil(np.log10(np.max(abs(raw_data))))
decimal_scaling = raw_data / (10**k)

# 打印结果
print(min_max)
print(z_score)
print(decimal_scaling)

输出结果

min_max
Out[10]: 
array([[0.07438017, 0.93729097, 0.92351974, 1.        ],
       [0.61983471, 0.        , 0.        , 0.85114596],
       [0.21487603, 0.11956522, 0.81332237, 0.        ],
       [0.        , 1.        , 1.        , 0.56381182],
       [1.        , 0.94230769, 0.99671053, 0.80434258],
       [0.26446281, 0.83862876, 0.81496711, 0.90952955]])

z_score
Out[11]: 
array([[-0.83193017,  0.71866807,  0.47630463,  0.92955909],
       [ 0.74435857, -1.54432887, -2.18263537,  0.4858732 ],
       [-0.4259164 , -1.2556504 ,  0.15903129, -2.0511184 ],
       [-1.04687863,  0.87007286,  0.69650179, -0.37057719],
       [ 1.84298406,  0.73078046,  0.68703095,  0.34636743],
       [-0.28261743,  0.48045787,  0.16376671,  0.65989587]])

decimal_scaling
Out[12]: 
array([[ 0.0078,  0.0521,  0.0602,  0.2862],
       [ 0.0144, -0.06  , -0.0521,  0.2245],
       [ 0.0095, -0.0457,  0.0468, -0.1283],
       [ 0.0069,  0.0596,  0.0695,  0.1054],
       [ 0.019 ,  0.0527,  0.0691,  0.2051],
       [ 0.0101,  0.0403,  0.047 ,  0.2487]])

两种方法对比

观察仔细的小伙伴,应该就可以发现,两种方法得到的结果存在差异。这是为什么呢?
主要原因还是两种方法的实现不同,处理的对象主体也不同。我们可以通过测试每一步的输出,以及查看源码来发现和解决问题。

接下来,主要针对两种方法进行小数定标规范化后,得到的结果存在差异的原因,进行分析。

在方法一中,处理的数据是 DataFrame 对象。原始数据(raw_data)被转换成 Pandas 的 DataFrame 对象(data),对 data 执行统计计算,例如求均值,方差,最大值时,默认是对每一列求均值,方差,最大值。(也可以通过修改axis的取值,对每一行执行操作。)本例中的 data 有4列,对 data 求最大值,则有4个结果。

decimal_scaling = data / 10**np.ceil(np.log10(data.abs().max()))

data
Out[42]: 
     0    1    2     3
0   78  521  602  2862
1  144 -600 -521  2245
2   95 -457  468 -1283
3   69  596  695  1054
4  190  527  691  2051
5  101  403  470  2487

type(data)  # data是DataFrame类型
Out[43]: pandas.core.frame.DataFrame

data.describe()  # 对data的描述
Out[44]: 
                0           1           2            3
count    6.000000    6.000000    6.000000     6.000000
mean   112.833333  165.000000  400.833333  1569.333333
std     45.866836  542.640581  462.659882  1523.351656
min     69.000000 -600.000000 -521.000000 -1283.000000
25%     82.250000 -242.000000  468.500000  1303.250000
50%     98.000000  462.000000  536.000000  2148.000000
75%    133.250000  525.500000  668.750000  2426.500000
max    190.000000  596.000000  695.000000  2862.000000

data.abs().max()  # 对data的每一列取绝对值后,再求每一列的最大值
Out[45]: 
0     190
1     600
2     695
3    2862
dtype: int32

方法二中,处理的数据是 numpy 的数组 ndarray。当对数据取均值,最大值等统计值时,是以整个数组为主体,最后求得的均值,最大值,都分别只有一个。

k = np.ceil(np.log10(np.max(abs(raw_data))))
decimal_scaling = raw_data / (10**k)

raw_data
Out[13]: 
array([[   78,   521,   602,  2862],
       [  144,  -600,  -521,  2245],
       [   95,  -457,   468, -1283],
       [   69,   596,   695,  1054],
       [  190,   527,   691,  2051],
       [  101,   403,   470,  2487]])

type(raw_data)
Out[14]: numpy.ndarray

np.mean(raw_data)  # 求均值
Out[15]: 562.0

# 对所有数值求绝对值后,再求出所有数值当中的最大值,只返回一个结果
np.abs(raw_data).max()  
Out[17]: 2862

结论:具体问题具体分析,根据实际场景的需要,选择合适的计算方式。

  • 10
    点赞
  • 70
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值