(Python) 如何使用 [:] 语法对数组的每个元素使用条件语句?

(Python) How to use conditional statements on every element of array using [:] syntax?

如果我需要询问 numpy.ndarray 整数的每个元素的条件,我是否必须使用 for 循环

for i in range(n):
    if a[i] == 0:
        a[i] = 1   

或者我可以使用 [:] 语法提问吗

if a[:] == 0:
    #...

我知道前面的是错误的,但是有什么办法可以做类似的事情吗?

您可以使用 all 内置函数来完成您的要求:

all(i == 0 for i in a)

示例:

>>> a = [1, 0, 0, 2, 3, 0]
>>> all(i == 0 for i in a)
False

但是请注意,在幕后,all 仍然使用 for 循环。 It's just implemented in C:

for (;;) {
    item = iternext(it);
    if (item == NULL)
        break;
    cmp = PyObject_IsTrue(item);
    Py_DECREF(item);
    if (cmp < 0) {
        Py_DECREF(it);
        return NULL;
    }
    if (cmp == 0) {
        Py_DECREF(it);
        Py_RETURN_FALSE;
    }

编辑:鉴于您最近的编辑,您可能想要的是使用三元运算符的列表理解:

[1 if  i == 0 else i for i in a]

示例:

>>> a = [1, 0, 0, 2, 3, 0]
>>> [1 if  i == 0 else i for i in a]
[1, 1, 1, 2, 3, 1]

一次 numpy.ndarray 的每个元素测试一个条件,如标题所示:

为此使用 numpy 的 np.all

if np.all(a == 0):
    # ...

尽管它不是懒惰的,np.all 是向量化的并且非常快

# arrays of zeros

>>> a = np.zeros((1000000))
>>> %timeit np.all(a == 0)                    # vectorized, very fast 
10000 loops, best of 3: 34.5 µs per loop

>>>%timeit all(i == 0 for i in a)             # not vectorized...
100 loops, best of 3: 19.3 ms per loop


# arrays of non-zeros

>>> b = np.ones((1000000))
>>> %timeit np.all(b == 0)                    # not lazy, iterates through all array
1000 loops, best of 3: 498 µs per loop

>>> %timeit all(i == 0 for i in b)            # lazy, return false at first 1
1000000 loops, best of 3: 561 ns per loop


# n-D arrays of zeros

>>> c = a.reshape((100, 1000))                # 2D array
>>> %timeit np.all(c == 0)
10000 loops, best of 3: 34.7 µs per loop      # works on n-dim arrays

>>> %timeit all(i == 0 for i in c)            # wors for a 1D arrays only
...
ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()

用于测试 numpy.ndarray 的每个元素的条件 :

for i in range(n):
    if a[i] == 0:
        a[i] = 1  

可以换成np.where

a = np.where(a == 0, 1, a)  # set value '1' where condition is met

编辑:根据 OP 的评论进行精确度

如果您不仅需要检查,还需要映射所有 0 --> 1,请使用 map:

map(lambda x: 1 if x==0 else x, a)

假设 a 是您的数组,并且您想将大于 1 的 a 的值更改为等于 1:

a[a > 1] = 1

这是有效的,因为表达式 a > 1 创建了一个 mask array,并且当掩码数组用作索引(它在这里)时,该操作仅适用于 True 指数。