考虑以下两个相同代码的实现。我本以为他们是一模一样的,但事实并非如此
这是一个Python/Numpy bug还是一个微妙的问题?如果是后者,有什么规则可以让人明白为什么它不能像预期的那样工作
我使用的是多个数据数组,必须逐项处理每个数组,每个数组都由表根据其元数据进行操作
在现实世界的例子中,“n”是多个因子和偏移量,但下面的代码仍然说明了一个问题,即除了一个例子外,我在所有情况下都得到了错误的结果
import numpy as np
# Change the following line to True to show different behaviour
NEEDS_BUGS = False # Changeme
# Create some data
data = np.linspace(0, 1, 10)
print(data)
# Create an array of vector functions each of which does a different operation on a set of data
vfuncd = dict()
# Two implementations
if NEEDS_BUGS:
# Lets do this in a loop because we like loops - However WARNING this does not work!!
for n in range(10):
vfuncd[n] = np.vectorize(lambda x: x * n)
else:
# Unwrap the loop - NOTE: Spoiler - this works
vfuncd[0] = np.vectorize(lambda x: x * 0)
vfuncd[1] = np.vectorize(lambda x: x * 1)
vfuncd[2] = np.vectorize(lambda x: x * 2)
vfuncd[3] = np.vectorize(lambda x: x * 3)
vfuncd[4] = np.vectorize(lambda x: x * 4)
vfuncd[5] = np.vectorize(lambda x: x * 5)
vfuncd[6] = np.vectorize(lambda x: x * 6)
vfuncd[7] = np.vectorize(lambda x: x * 7)
vfuncd[8] = np.vectorize(lambda x: x * 8)
vfuncd[9] = np.vectorize(lambda x: x * 9)
# Prove we have multiple different vectorised functions
for k, vfunc in vfuncd.items():
print(k, vfunc)
# Do the work
res = {k: vfuncd[k](data) for k in vfuncd.keys()}
# Show the result
for k, r in res.items():
print(k, r)
我不知道你到底想实现什么,也不知道这是不是一个坏主意(就
np.vectorize
),但你面临的问题是因为the way python makes closures。引述对相关问题的回答:换句话说,当您在
n
上进行闭包时,实际上并没有关闭n
的状态,只是关闭了名称。因此,当n
更改时,闭包中的值也会更改。这对我来说很意外,但是others find it natural下面是一个使用
partial
的修复程序:或其他使用工厂方法的
由于
data
数组可以与简单的我们不需要复杂的
np.vectorize
来查看关闭问题。一个简单的lambda
就足够了如果我们使用适当的
numpy
“矢量化”,我们就不会遇到闭包问题:或者一个简单的迭代就是我们需要一个字典:
np.vectorize
有一个速度免责声明。但是,如果函数只接受标量输入,并且我们想要numpy广播的灵活性,也就是说,对于2个或更多参数,这是合理的创建多个
vectorize
显然是一种“反模式”。我宁愿看到一个带有适当参数的vectorize
:f
也可以生成数组Out[18]
(但速度较慢):python变量n似乎绑定到向量化表达式:
这会在创建要绑定的新对象时修复它:
事实上,这对性能有影响,因为我假设必须重复获取python变量的值
相关问题 更多 >
编程相关推荐