我正在尝试遍历numpy数组的每个元素,并以半随机方式更改其值。这样做的原因是,我将该方法应用于不同的数组:我希望更改它们,但我不希望它们以相同的方式更改。
这是我到目前为止尝试过的:
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
另一种可能性:
for element in np.nditer(smatrix, op_flags=['readwrite']):
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
但是,结果数组看起来与初始数组完全相同...
我对编程还比较陌生,并且在这个问题上停留了很长时间。如果有人能给我一些解决方法的提示,最好是简短的解释,那将是非常棒的。谢谢!!
答案 0 :(得分:0)
如果要将变换应用于numpy.array
的每个单元格,那么numpy.vectorize
是正确的工具。
首先,您需要使用函数,该函数将使用单个单元格的内容作为输入,该函数本身将被馈送到vectorize
且需要return
的期望值,请参见代码:
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)
输出(由于部分随机,可能与您有所不同):
[-4.48922564 0.19609667 0. 1. 1.9 ]
您可以检查它对所有值的作用。请注意,我添加了“对元素不执行操作”(return x
)作为安全措施,以防元素大于1
。
有关numpy.vectorize
的更多信息,请阅读documentation。
编辑:已修正在评论中报告的问题,问题是f
有时return
编辑了int
,有时float
,而它应该始终return
{{ 1}}。
答案 1 :(得分:0)
我认为nditer
需要更强有力的免责声明。对于初学者来说,它不是一个很好的迭代工具。使用权利很难,而且速度不是特别快。这个Python版本确实是在编译代码中使用它的踏脚石,如cython
主页末尾的nditer
示例所示:
https://docs.scipy.org/doc/numpy/reference/arrays.nditer.html
可以使用更快的方法进行这种数组计算,但是我将尝试解释为什么您的nditer
无法正常工作。
问题在于基本的Python迭代。像这样的循环:
alist = [0,0,0]
for element in alist:
element = 1
alist
未修改。 element=1
只是重新分配了element
变量,但没有修改迭代变量本身。相反,您可以对element
本身进行突变。
对于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]])
如果不清楚,请仔细查看https://docs.scipy.org/doc/numpy/reference/generated/numpy.nditer.html中的示例。注意使用out
参数和类似x[:] = [-1, -2, -3]
的表达式。
如果这种关于变异变量的说法令人困惑,则很好地表明nditer
在这一点上太先进了。