【问题标题】:Adding arrays which may contain 'None'-entries添加可能包含“无”条目的数组
【发布时间】:2018-10-07 12:06:57
【问题描述】:

我有一个关于添加 numpy 数组的问题。 假设我已经定义了一个函数

def foo(a,b):
    return a+b

采用两个相同形状的数组并简单地返回它们的总和。 现在,我必须处理某些条目可能为 None 的情况。 我想处理这些条目,因为它们对应于 float(0),这样

[1.0,None,2.0] + [1.0,2.0,2.0] 

会加起来

[2.0,2.0,4.0]

你能提供一个已经实现的解决方案吗?

TIA

【问题讨论】:

  • [1.0,None,2.0] 是一个列表,而不是一个 numpy 数组。
  • 几个答案建议nan_to_num。看它的代码。它使用where(或者更确切地说是copy_towhere 参数)将nan 替换为0。 (它还处理inf。)您可以自己轻松地进行替换,而且可能更快。
  • 一个 2011 年的问题:convert nan value to zero;和一个当前的问题,Implicitly convert/evaluate NaNs to/as zeros whenever occurs in NumPy 试图在低级别执行此操作。

标签: python numpy padding


【解决方案1】:

您可以使用column_stack 沿第二个轴连接两个数组,然后使用np.nansum() 对第二个轴上的项目求和。

In [15]: a = np.array([1.0,None,2.0], dtype=np.float)
# Using dtype here is necessary to convert None to np.nan

In [16]: b = np.array([1.0,2.0,2.0]) 

In [17]: np.nansum(np.column_stack((a, b)), 1)
Out[17]: array([2., 2., 4.])

【讨论】:

    【解决方案2】:

    我建议numpy.nan_to_num

    >>> np.nan_to_num(np.array([1.0,None,2.0], dtype=np.float))
    array([ 1.,  0.,  2.])
    

    那么,

    >>> def foo(a,b):
    ...         return np.nan_to_num(a) + np.nan_to_num(b)
    ...
    >>> foo(np.array([1.0,None,2.0], dtype=np.float), np.array([1.0,2.0,2.0], dtype=np.float))
    array([ 2.,  0.,  4.])
    

    【讨论】:

    • 如果无法重新定义数组,您可以使用np.nan_to_num(a.astype(np.float)) + np.nan_to_num(b.astype(np.float))
    • @pault,感谢您指出astype(np.float) 呼叫。幸运的是,只需要一个np.nan_to_num,因为NaN + anything = NaN
    • @sushain97 不,这不对。 OP 想要将 None + 2 转换为 2,并且可能还将 2 + None 转换为 2,但您要将它们都转换为 0
    • 啊,好点子。我修改了我的答案。谢谢你的收获。
    【解决方案3】:

    通常,这个问题的答案是使用浮点数组,而不是任意对象数组,然后使用np.nan 而不是None。 NaN 具有明确定义的算术语义。 (此外,使用浮点数组代替对象将使您的代码在时间和空间上显着提高效率。)


    请注意,如果您使用显式 dtypefloatnp.float64 构建数组,则不必手动将 None 转换为 np.nan。这两个是等价的:

    >>> a = np.array([1.0,np.nan,2.0])
    >>> a = np.array([1.0,None,2.0],dtype=float)
    

    这意味着,如果出于某种原因,您确实需要包含实际 None 的任意对象数组,您可以这样做,然后将其动态转换为浮点数组以获得 NaN 的好处:

    >>> a.astype(float) + b.astype(float)
    

    无论如何,在这种情况下,仅使用 NaN 是不够的:

    >>> a = np.array([1.0,np.nan,2.0])
    >>> b = np.array([1.0,2.0,2.0])
    >>> a + b
    array([ 2., nan,  4.])
    

    这是因为 NaN 的语义是任何对 NaN 的操作的结果都返回 NaN。但是你想把它当作0。

    但它确实使问题很容易解决。解决这个问题的最简单方法是使用函数nan_to_num

    >>> np.nan_to_num(a, 0)
    array([1., 0., 2.0])
    >>> np.nan_to_num(a, 0) + np.nan_to_num(b, 0)
    array([2., 2., 4.])
    

    【讨论】:

    • 您可以使用a.astype(np.float)None 转换为nan
    • @pault 当然。但最好首先将a 构造为浮点数。但无论如何我都会编辑答案以指出这一点。
    猜你喜欢
    • 2016-07-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-11-10
    • 1970-01-01
    • 1970-01-01
    • 2014-03-01
    • 1970-01-01
    相关资源
    最近更新 更多