【问题标题】:Perform numpy operation with None/NaN in array使用数组中的 None/NaN 执行 numpy 操作
【发布时间】:2021-04-25 23:34:56
【问题描述】:

有什么办法可以使这个工作吗?我正在处理的数组由None 组成,这意味着在处理中忽略该值。例如,我想规范化这个数组:

output = np.array([[1,2,None,4,5],[None,7,8,9,10]])
mu = np.mean(output, axis=(0,1), keepdims=True)
sd = np.std(output, axis=(0,1), keepdims=True)
normalized_output = (output - mu)/sd

预期结果:

array([[-1.5666989 , -1.21854359, None, -0.52223297, -0.17407766],
       [ None,  0.52223297,  0.87038828,  1.21854359,  1.5666989 ]])

编辑:按照建议,最好使用 NaN 而不是 None。如何让它与 NaN 一起工作:

output = np.array([[1,2,np.NAN,4,5],[np.NAN,7,8,9,10]])
mu = np.mean(output, axis=(0,1), keepdims=True)
sd = np.std(output, axis=(0,1), keepdims=True)
normalized_output = (output - mu)/sd
print(normalized_output)
# array([[nan, nan, nan, nan, nan],
#        [nan, nan, nan, nan, nan]])

【问题讨论】:

  • 如果向量中没有 None,这是一个非常糟糕的信号:这意味着数组中的值是 object 类型,因此所有相关的计算都没有优化。考虑使用原生的 NaN 值。
  • 感谢您的意见。我不知道 None 对矢量有害。我可以使用where 将其更改为 NaN。根据您的建议更新了问题。
  • 如果你想保持你的值是整数,使用掩码数组而不是 NaN。我认为 NaN 是错误计算的结果(例如 0/0),而掩码值表示该值的缺失:两个不同的东西。 NaN 通常用于两者,但这可能会导致混淆。
  • 在计算平均值时也会考虑 NaN。有特殊的nanmean 函数,但在这里,我认为掩码数组更合适。
  • 这能回答你的问题吗? NumPy: calculate averages with NaNs removed

标签: python numpy


【解决方案1】:

您可以使用 numpy masked arrays 进行跳过某些值的计算。

已经存在一个函数来创建一个屏蔽数组来屏蔽NaN 值:ma.masked_invalid

可以这样使用:

import numpy as np
from numpy import ma


output = ma.masked_invalid([[1,2,np.NAN,4,5],[np.NAN,7,8,9,10]])

mu = np.mean(output, axis=(0,1), keepdims=True)
sd = np.std(output, axis=(0,1), keepdims=True)
normalized_output = (output - mu)/sd
print(normalized_output)

输出(-- 表示无效值):

[[-1.5461980716652028 -1.2206826881567392 -- -0.5696519211398116
  -0.24413653763134782]
 [-- 0.40689422938557973 0.7324096128940435 1.0579249964025073
  1.3834403799109711]]

【讨论】:

    【解决方案2】:

    您可以使用np.nanstdnp.nanmean 函数代替np.stdnp.mean

    output = np.array([[1,2,np.nan,4,5],[np.nan,7,8,9,10]])
    mu = np.nanmean(output, axis=(0,1), keepdims=True)
    sd = np.nanstd(output, axis=(0,1), keepdims=True)
    normalized_output = (output - mu)/sd
    

    你会得到这样的输出

    array([[-1.54619807, -1.22068269,         nan, -0.56965192, -0.24413654],
          [        nan,  0.40689423,  0.73240961,  1.057925  ,  1.38344038]])
    

    它与您想要的输出不同,因为np.nanstd 忽略了数组中存在的 Nan 值,因此您有 8 个元素而不是 10 个。

    【讨论】:

    • 请注意,这会将outputdtypeint64 更改为float64
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-04-03
    • 2018-12-09
    • 1970-01-01
    • 1970-01-01
    • 2010-11-27
    • 1970-01-01
    相关资源
    最近更新 更多