Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/clojure/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 如何根据条件设置`np.array()`中的单元格值?_Python_Arrays_Numpy - Fatal编程技术网

Python 如何根据条件设置`np.array()`中的单元格值?

Python 如何根据条件设置`np.array()`中的单元格值?,python,arrays,numpy,Python,Arrays,Numpy,我有一个numpy数组和该数组中的有效值列表: import numpy as np arr = np.array([[1,2,0], [2,2,0], [4,1,0], [4,1,0], [3,2,0], ... ]) valid = [1,4] 是否有一种很好的pythonic方法将所有数组值设置为零,而这些值不在有效值列表中,并且就地执行?执行此操作后,列表应如下所示: [[1,0,0], [0,0,0], [4,1,0], [4,1,0], [0,0,0]

我有一个
numpy
数组和该数组中的有效值列表:

import numpy as np
arr = np.array([[1,2,0], [2,2,0], [4,1,0], [4,1,0], [3,2,0], ... ])
valid = [1,4]
是否有一种很好的pythonic方法将所有数组值设置为零,而这些值不在有效值列表中,并且就地执行?执行此操作后,列表应如下所示:

               [[1,0,0], [0,0,0], [4,1,0], [4,1,0], [0,0,0], ... ]
以下操作将在内存中创建阵列的副本,这对大型阵列不好:

arr = np.vectorize(lambda x: x if x in valid else 0)(arr)
这让我很恼火,现在我在每个数组元素上循环,如果它在
有效的
列表中,则将其设置为零

编辑:我发现了一个建议,即没有现成的功能来实现这一点。也不要改变我的空白。在
arr
中更容易看到这些更改。

您可以使用
就地更新-

np.place(arr,~np.in1d(arr,valid),0)
样本运行-

In [66]: arr
Out[66]: 
array([[1, 2, 0],
       [2, 2, 0],
       [4, 1, 0],
       [4, 1, 0],
       [3, 2, 0]])

In [67]: np.place(arr,~np.in1d(arr,valid),0)

In [68]: arr
Out[68]: 
array([[1, 0, 0],
       [0, 0, 0],
       [4, 1, 0],
       [4, 1, 0],
       [0, 0, 0]])
In [70]: arr
Out[70]: 
array([[1, 2, 0],
       [2, 2, 0],
       [4, 1, 0],
       [4, 1, 0],
       [3, 2, 0]])

In [71]: np.put(arr,np.where(~np.in1d(arr,valid))[0],0)

In [72]: arr
Out[72]: 
array([[1, 0, 0],
       [0, 0, 0],
       [4, 1, 0],
       [4, 1, 0],
       [0, 0, 0]])

同样,也可以使用
np.put
-

np.put(arr,np.where(~np.in1d(arr,valid))[0],0)
样本运行-

In [66]: arr
Out[66]: 
array([[1, 2, 0],
       [2, 2, 0],
       [4, 1, 0],
       [4, 1, 0],
       [3, 2, 0]])

In [67]: np.place(arr,~np.in1d(arr,valid),0)

In [68]: arr
Out[68]: 
array([[1, 0, 0],
       [0, 0, 0],
       [4, 1, 0],
       [4, 1, 0],
       [0, 0, 0]])
In [70]: arr
Out[70]: 
array([[1, 2, 0],
       [2, 2, 0],
       [4, 1, 0],
       [4, 1, 0],
       [3, 2, 0]])

In [71]: np.put(arr,np.where(~np.in1d(arr,valid))[0],0)

In [72]: arr
Out[72]: 
array([[1, 0, 0],
       [0, 0, 0],
       [4, 1, 0],
       [4, 1, 0],
       [0, 0, 0]])

使用布尔值进行索引也可以:

>>> arr = np.array([[1, 2, 0], [2, 2, 0], [4, 1, 0], [4, 1, 0], [3, 2, 0]])
>>> arr[~np.in1d(arr, valid).reshape(arr.shape)] = 0
>>> arr
array([[1, 0, 0],
       [0, 0, 0],
       [4, 1, 0],
       [4, 1, 0],
       [0, 0, 0]])

我怀疑这也会创建一个临时副本,因为您要重塑一个数组,并将其与原始数组相乘。所以它不符合我的“就地”要求。您可以在操作后键入
arr
来查看这一点。它仍然会给你原来的数组三三两两。你真的应该只做一个新的答案,而不是一遍又一遍地编辑你的旧答案。这使讨论变得困难。使用
np.place(arr,~np.in1d(arr,valid),0)
in1d部分仍然创建整个数组的内存副本,与
np.put(arr,np.where(~np.in1d(arr,valid))[0]相同。
@con-f-use,据我所知,
~np.in1d(arr,valid)
将是一个布尔数组,因此比典型的整数数组占用更少的内存,如果我在这里出错,请更正。然后它在
arr
中进行现场更新,因此没有涉及其他副本。同意,
np.zeroes((100),dtype=bool)。nbytes
np.zeroes((100),dtype=float)。nbytes
。但我的问题是,在某些目标系统上,
arr
已经很难放入内存,甚至比原来的阵列小1/8的阵列也可能会导致问题。这也是一个主要问题;-)不过,我还是要感谢你花了这么多时间!我确信没有就地功能,循环是不可避免的。请看我的编辑。@con-f-use是的,我想这是你需要做的权衡,对不起!我想是情不自禁:)或者如果你喜欢中间立场,可以分块做!