python,numpy布尔数组:where语句中的取反

17 投票
2 回答
41387 浏览
提问于 2025-04-16 11:47

使用:

import numpy as np
array = get_array()

我需要做以下事情:

for i in range(len(array)):
    if random.uniform(0, 1) < prob:
        array[i] = not array[i]

这里的数组是一个 numpy.array。

我希望能做一些类似于:

array = np.where(np.random.rand(len(array)) < prob, not array, array)

但是我得到的结果是(指的是“不是数组”):

一个包含多个元素的数组的真值是模糊的。请使用 a.any() 或 a.all()

为什么我可以获取数组的值,但不能获取它的否定呢?

目前我用以下方法解决了这个问题:

array = np.where(np.random.rand(len(array)) < prob, - array + 1, array)

但我觉得这样看起来真的很笨重。

谢谢你的帮助

附言:我不在乎这个语句是否会修改数组。我只需要操作的结果。

还有一个问题:我想做这个改变有两个原因:可读性和效率。这样做真的能提高性能吗?再次感谢你

2 个回答

4

putmask 是一个非常高效的工具,如果你想替换某些特定的元素,它会帮你快速完成这个任务。

import numpy as np

np.putmask(array, numpy.random.rand(array.shape) < prob, np.logical_not(array))
33

我建议使用

array ^= numpy.random.rand(len(array)) < prob

这可能是获得想要结果的最有效方法。它会直接在原数组上进行修改,利用“异或”操作来反转那些随机条件判断为 True 的元素。

为什么我可以获取数组的值,但不能获取它的否定值呢?

你也不能直接获取数组的真假值:

>>> bool(array)
ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()

not 操作符会隐式地尝试把它后面的内容转换成 bool(真假值),然后返回相反的真假值。你无法重载 not 来实现其他的功能。如果想要对一个包含 bool 值的 NumPy 数组进行否定,可以使用

~array

或者

numpy.logical_not(array)

或者

numpy.invert(array)

不过。

撰写回答