(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 > 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如何对每个点进行标记注释?