Python 根据numpy数组的值更改其各个元素
我试图迭代numpy数组的每个元素,并以半随机的方式更改其值。原因是,我将把该方法应用于不同的数组:我希望更改它们,但不希望以相同的方式更改它们 以下是我迄今为止所做的尝试:Python 根据numpy数组的值更改其各个元素,python,arrays,numpy,iteration,numpy-ndarray,Python,Arrays,Numpy,Iteration,Numpy Ndarray,我试图迭代numpy数组的每个元素,并以半随机的方式更改其值。原因是,我将把该方法应用于不同的数组:我希望更改它们,但不希望以相同的方式更改它们 以下是我迄今为止所做的尝试: with np.nditer(smatrix, op_flags=['readwrite']) as it: for element in it: if element < 0: element = element - uniform(0.1,0.2)
with np.nditer(smatrix, op_flags=['readwrite']) as it:
for element in it:
if element < 0:
element = element - uniform(0.1,0.2)
if 0 <= element < 0.05:
element = uniform(0.15,0.3)
elif 0.05 <= element < 1:
element = 0
elif 1 == element:
element = 1
与np.nditer(smatrix,op_flags=['readwrite'])一样:
对于其中的元素:
如果元素<0:
元素=元素-均匀(0.1,0.2)
如果0如果您想将转换应用于numpy.array
的每个单元格,则numpy.vectorize
是正确的工具。
首先,您需要函数,该函数将使用单个单元格的内容作为输入,它本身将被馈送到矢量化
,并且返回所需的值,请参见代码:
import numpy as np
import random
def f(x):
if x < 0:
return x-random.uniform(0.1,0.2)
if 0 <= x < 0.05:
return random.uniform(0.15,0.3)
if 0.05 <= x < 1:
return 0.0
if x == 1:
return 1.0
return x
vf = np.vectorize(f)
data = np.array([-4.3,0.03,0.9,1.0,1.9])
altered_data = vf(data)
正如您可以检查的那样,它对所有值都起到了预期的作用。请注意,我添加了“不对元素执行任何操作”行为(返回x
)作为安全措施,以防元素大于1
有关numpy.vectorize
的更多信息,请阅读
编辑:修复了评论中报告的问题,问题是f
有时return
edint
有时float
,而它应该总是return
float,我认为nditer
需要一个更强有力的免责声明。对于初学者来说,它不是一个好的迭代工具。正确使用它很难,而且速度也不是特别快。这个Python版本实际上是在编译代码中使用它的垫脚石,如主nditer
页面末尾的cython
示例所示:
有更快的方法来进行这种数组计算,但我将尝试解释为什么nditer
不起作用
问题在于基本Python迭代。在循环中:
alist = [0,0,0]
for element in alist:
element = 1
alist
未被修改。element=1
只重新分配element
变量,但不修改迭代变量本身。如果可能的话,您可以使用mutate元素本身
使用nditer
时,迭代变量是ndarray
本身,并且是可变的:
In [69]: smatrix = np.zeros((2,2),int)
In [70]: with np.nditer(smatrix, op_flags=['readwrite']) as it:
...: for element in it:
...: print(element, type(element))
...: element[...] = 1
...:
0 <class 'numpy.ndarray'>
0 <class 'numpy.ndarray'>
0 <class 'numpy.ndarray'>
0 <class 'numpy.ndarray'>
In [71]: smatrix
Out[71]:
array([[1, 1],
[1, 1]])
[69]中的:smatrix=np.zero((2,2),int)
在[70]中:使用np.nditer(smatrix,op_flags=['readwrite']),如下所示:
…:对于其中的元素:
…:打印(元素,类型(元素))
…:元素[…]=1
...:
0
0
0
0
在[71]中:smatrix
出[71]:
数组([[1,1],
[1, 1]])
如果这不清楚,请更仔细地查看中的示例。注意使用out
参数和x[:]=[-1,-2,-3]
等表达式
如果这种关于变异变量的说法令人困惑,那么这就很好地表明,nditer
在这一点上太高级了。我用不同的2D数组尝试了您的解决方案,发现了一个问题,如果第一个值=1示例:data=np.array([[0.02,0,0.1,1],[1,0.05,0,0.01])[[0.17426108 0.25596603 0.1.][1.0.0.29732222 0.23448857]]data=np.array([1,0,0.1,1],[1,0.05,0,0.01])[[1,0,0 1][1,0]vectorize
执行一次尝试计算以确定返回的数据类型。若要跳过此操作,请定义一个otypes
参数。vectorize
如果必须在多维数组上使用标量函数,则非常方便,但它比更显式的Python迭代慢。
alist = [0,0,0]
for element in alist:
element = 1
In [69]: smatrix = np.zeros((2,2),int)
In [70]: with np.nditer(smatrix, op_flags=['readwrite']) as it:
...: for element in it:
...: print(element, type(element))
...: element[...] = 1
...:
0 <class 'numpy.ndarray'>
0 <class 'numpy.ndarray'>
0 <class 'numpy.ndarray'>
0 <class 'numpy.ndarray'>
In [71]: smatrix
Out[71]:
array([[1, 1],
[1, 1]])