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

Posted

技术标签:

【中文标题】(Python)如何使用 [:] 语法对数组的每个元素使用条件语句?【英文标题】:(Python) How to use conditional statements on every element of array using [:] syntax? 【发布时间】:2018-02-01 13:38:49 【问题描述】:

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

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

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

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

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

【问题讨论】:

#... 应该做什么。你想为每个元素调用一个代码片段吗? 列表理解可以在这里工作,具体取决于您想要做什么 你有 list 还是 array a的类型是什么? Python 数组还是 numpy 数组? @WillemVanOnsem 例如,如果一个元素大于 1,则为每个元素分配 1 给该元素 【参考方案1】:

您可以使用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]

【讨论】:

嗯...我认为这实际上并没有满足 OP 的要求。看起来 OP 想要对数组的每个元素进行操作,而不是检查所有内容的真实性。 OP 要么需要使用条件或向量化的 numpy 操作来进行列表理解。 很好地使用了列表 comp 中的三元! +1,尽管起初我很难阅读,因为我的大脑预计 if 会稍后出现。 @CodyPiersall 谢谢。但是现在 OP 已经更新了他们的问题,您的解决方案显然是更好的解决方案!你有我的赞成票。 @ChristianDean 谢谢你的回答,我意识到我的问题不够清楚 很高兴为您提供帮助,@Juan。【参考方案2】:

一次测试 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 的 cmets 的精度

【讨论】:

【参考方案3】:

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

a[a > 1] = 1

之所以有效,是因为表达式 a &gt; 1 创建了一个 mask array,并且当掩码数组用作索引时(在此处),该操作仅适用于 True 索引。

【讨论】:

这是合乎逻辑的答案,但它应该是a[a == 0] = 1。所有其他答案都不必要地复杂。 @C8H10N4O2 根据原始问题,您是对的,但我是根据 OP 对 OP 问题的评论来建立这个例子的。 好的,我现在明白了。这一定是个骗子。 @C8H10N4O2 公平地说,OP 已经相当广泛地编辑了他们的问题。当我的答案和其他几个人发布时,不清楚 OP 是否正在使用 NumPy,甚至是他们真正想要的。请参阅edit history。 你可以看到我是一个新手,我认为我的问题已经很清楚了,不管在“if”语句中做了什么,或者我是否使用了 NumPy 数组【参考方案4】:

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

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

【讨论】:

以上是关于(Python)如何使用 [:] 语法对数组的每个元素使用条件语句?的主要内容,如果未能解决你的问题,请参考以下文章

不用循环,python numpy 数组如何对每个元素进行操作?

在 Python 中使用循环对数组进行切片并为每个小数组赋予特定的名称

python的Matplotlib如何对每个点进行标记注释?

数据结构-列表基本语法

如何使用 JavaScript spread... 语法更改对象的一个​​字段,该字段属于数组并通过名称-值对访问?

如何在 Fortran 中初始化二维数组