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

Posted

技术标签:

【中文标题】在 0 和 1 之间进行归一化,忽略 NaN【英文标题】:Normalise between 0 and 1 ignoring NaN 【发布时间】:2017-02-07 01:54:58 【问题描述】:

对于从xy 可能包含NaN 的数字列表,我如何在0 和1 之间进行归一化,忽略NaN 值(它们保持为NaN)。

通常我会使用来自sklearn.preprocessingMinMaxScaler (ref page),但这不能处理NaN,并建议根据平均值或中值等来估算值。它不提供忽略所有NaN 值。

【问题讨论】:

使用np.nanmaxnp.nanmin 代替np.maxnp.min,其余的应该可以正常工作。 所以,基本上:(a-np.nanmin(a))/(np.nanmax(a) - np.nanmin(a)). pandas 也可以优雅地处理NaNs,所以一个简单的(a - a.min()) / (a.max() - a.min()) 就可以完成这项工作。 【参考方案1】:

考虑pd.Seriess

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


选项 1 最小最大缩放

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


不是 OP 要求的内容 我把这些放进去是因为我想

选项 2 乙状结肠

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

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


选项 3 tanh(双曲正切)

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

【讨论】:

-1 OP 通过引用MinMaxScaler 明确表示他对线性缩放感兴趣。选项 2 和 3 与 OP 无关,在我看来,这让读者感到困惑,而不是帮助他们。 @user40314 感谢您评论您投反对票的原因。我会用它来改进答案并使其更清晰。 谁曾否决过这个答案。我会很感激解释。这已被修改以提供 OP 想要的并已被接受。 我认为答案很明确,其他选项对寻求更广泛答案的其他读者很有用。【参考方案2】:

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

解决方案示例

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']])

【讨论】:

这个解决方案很好,但如果必须对多列进行归一化(或者可能必须考虑循环),则不够充分 在我的情况下,每个 MinMaxScaler 对象只需要一列。【参考方案3】:

现在(2020 年 6 月)sklearn 的行为似乎符合您(和我)的愿望: 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.  ]]

【讨论】:

以上是关于在 0 和 1 之间进行归一化,忽略 NaN的主要内容,如果未能解决你的问题,请参考以下文章

处理数据时不进行归一化会有啥影响?归一化的作用是啥

matlab中啥叫归一化坐标

matlab中怎样将矩阵归一化处理?

傻傻分不清的:归一化(normalization)和标准化(standardization)

数据的归一化处理

笔记:错误记录- gdal读取哨兵1雷达数据分贝化数据归一化计算极值为nan,输出相同错误结果