忽略NaN,在0和1之间归一化

时间:2016-09-28 22:08:13

标签: python pandas numpy scikit-learn

对于可能包含x的{​​{1}}到y范围内的数字列表,如何在0和1之间进行标准化,忽略NaN值(它们保持不变作为NaN)。

通常情况下,我会使用NaN中的MinMaxScalerref page),但这不能处理sklearn.preprocessing并建议根据平均值或中位数等来估算值。 t提供忽略所有NaN值的选项。

3 个答案:

答案 0 :(得分:11)

考虑pd.Series s

s = pd.Series(np.random.choice([3, 4, 5, 6, np.nan], 100))
s.hist()

enter image description here

选项1
Min Max Scaling

new = s.sub(s.min()).div((s.max() - s.min()))
new.hist()

enter image description here

不是我要求的
我把它们放进去是因为我想

选项2
乙状结肠

sigmoid = lambda x: 1 / (1 + np.exp(-x))

new = sigmoid(s.sub(s.mean()))
new.hist()

enter image description here

选项3
tanh(双曲正切)

new = np.tanh(s.sub(s.mean())).add(1).div(2)
new.hist()

enter image description here

答案 1 :(得分:4)

这是一种不同的方法,我相信它正确地回答了OP,唯一的区别是这适用于数据帧而不是列表,您可以轻松地将列表放在数据帧中,如下所示。其他选项对我不起作用,因为我需要存储MinMaxScaler以便在做出预测后进行反向转换。因此,不是将整个列传递给MinMaxScaler,而是可以为目标和输入过滤掉NaN。

解决方案示例

import pandas as pd

import numpy as np

from sklearn.preprocessing import MinMaxScaler

scaler = MinMaxScaler(feature_range=(0, 1))

d = pd.DataFrame({'A': [0, 1, 2, 3, np.nan, 3, 2]})

null_index = d['A'].isnull()

d.loc[~null_index, ['A']] = scaler.fit_transform(d.loc[~null_index, ['A']])

答案 2 :(得分:1)

似乎sklearn现在(2020年6月)的行为符合您(和我)的期望: np.nan保持不变。 (主要是从sklearn文档粘贴的副本)

import sklearn
import numpy as np
from sklearn.preprocessing import MinMaxScaler
sklearn.__version__
# '0.23.1'
data = np.array([[-1, 2, 3], [-0.5, 6,3 ], [np.nan, 18, 3 ]])
print(data)
#[[-1.   2.   3. ]
# [-0.5  6.   3. ]
# [ nan 18.   3. ]]
scaler = MinMaxScaler()
data = scaler.fit_transform(data)
print(data)
#[[0.   0.   0.  ]
# [1.   0.25 0.  ]
# [ nan 1.   0.  ]]