我正在尝试向量化一个部分函数,该函数接受两个参数,两个参数都是列表,然后对列表中的成对元素执行某些操作(使用
zip
)。然而,我发现了一些意想不到的行为。
考虑以下代码:
import functools
import numpy as np
def f(l1,l2):
l1 = l1 if isinstance(l1,list) else [l1]
l2 = l2 if isinstance(l2,list) else [l2]
for e1,e2 in zip(l1,l2):
print(e1,e2)
f(['a','b'],[1,2])
fp = functools.partial(f,l1=['a','b'])
fp(l2=[1,2])
fv = np.vectorize(fp)
fv(l2=np.array([1,2]))
Jupyter Notebook 的输出如下:
a 1
b 2
a 1
b 2
a 1
a 1
a 2
array([None, None], dtype=object)
我有两个问题:
f
开头的类型检查是必要的,因为np.vectorize
似乎会自动完全展平任何输入(否则我会得到int32 not iterable
异常)。 有办法避免这种情况吗?fp
被向量化时,显然输出不是预期的输出 - 我不确定我是否理解 NumPy 在这里做什么,包括最终的空数组输出。无论我在列表、元组或数组中嵌套多少[1,2]
,输出似乎总是相同的。 如何修复我的代码,以便矢量化函数 fv
按预期运行 - 与 fp
相同?问题出在
isintance(l2, list)
。
numpy 数组不是列表。因此,您进入代码
l2 = [l2]
,使其成为一个维度为 1 的列表,第一个元素中包含 numpy 数组 [1, 2]。
我会摆脱多态性,其中 l1 和 l2 可能是列表或要打包到列表中的标量元素。