【问题标题】:NumPy, why equality check does not work for an array of objects?NumPy,为什么相等检查不适用于对象数组?
【发布时间】:2023-04-01 14:27:02
【问题描述】:

使用以下对象数组:

a = np.array([[1], [1, 2], [1, 2, 3], [1], [1]], dtype=object)
b = np.array([(1,), (1, 2), (1, 2, 3), (1,), (1,)], dtype=object)

以下相等性检查不起作用:

a==[1]
#array([False, False, False, False, False], dtype=bool)

b==(1,)
#array([False, False, False, False, False], dtype=bool)

如果我改用字符串:

c = np.array(['[1]', '[1, 2]', '[1, 2, 3]', '[1]', '[1]'])

平等检查有效:

c == '[1]'
#array([ True, False, False,  True,  True], dtype=bool)

为什么数组检查会这样?

如果我们遍历 a 或 b 并执行检查,它也会给出预期的结果:

[i==[1] for i in a]
#[True, False, False, True, True]

[i==(1,) for i in b]
#[True, False, False, True, True]

谢谢!

【问题讨论】:

    标签: python arrays object numpy equality


    【解决方案1】:

    NumPy 旨在在许多情况下自动将类似数组的对象视为数组。在这里,NumPy 看到 [1](1,) 是类数组对象并应用 broadcasting 规则。任一侧的 Length-1 轴扩展为另一个对象对应轴的长度,如果一个对象的尺寸小于另一个,则在左侧用其他对象在这些尺寸中的长度填充缺失的尺寸。因此,

    a == [1]
    

    给出与

    相同的结果
    a == numpy.array([1, 1, 1, 1, 1])
    

    这是一个由 5 个Falses 组成的数组。

    【讨论】:

    • 谢谢!您是否知道一种避免广播规则的方法,例如将 a 与 [1] element-wise 进行比较?
    • 不。我的建议是避免使用序列(或数组)作为数组元素。您可以尝试将它们包装在某种绝对非列表对象中,或者查看masked arrays 是否适合您的用例。
    • 您可以创建一个空形状-() 数组,然后用您的[1] 列表填充它。 c=np.empty([], dtype=object); c[()] = [1]。这避免了自动尝试将列表解释为它自己的数组。将ac 进行比较会得到你想要的结果。
    • @RobertKern:这个想法很聪明,但它会使代码变得更大,如果你不在所有地方都这样做,你忘记的地方就会默默地失败。我不会推荐它。
    猜你喜欢
    • 2018-04-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多