Python 或 MATLAB "cellfun" 的 Numpy 方法

Python or Numpy Approach to MATLAB's "cellfun"

是否有类似于 MATLAB "cellfun" 的 python 或 numpy 方法?我想将一个函数应用于一个对象,该对象是一个 MATLAB 元胞数组,具有约 300k 个不同长度的元胞。

一个非常简单的例子:

>>> xx = [(4,2), (1,2,3)]
>>> yy = np.exp(xx)

Traceback (most recent call last):
File "<pyshell#47>", line 1, in <module>
yy = np.exp(xx)
AttributeError: 'tuple' object has no attribute 'exp'

最 readable/maintainable 的方法可能是使用 list comprehension:

yy = [ np.exp(xxi) for xxi in xx ]

这依赖于 numpy.exp 将每个元组隐式转换为 numpy.ndarray,这反过来意味着您将获得 numpy.ndarray 的列表而不是列表元组。对于几乎所有目的,这可能没问题,但如果你绝对必须有元组,那也很容易安排:

yy = [ tuple(np.exp(xxi)) for xxi in xx ]

出于某些目的(例如,为了避免内存瓶颈),您可能更喜欢使用 generator expression 而不是列表理解(圆括号而不是方括号)。

MATLAB 单元试图像处理真实语言一样处理一般列表。但是作为 MATLAB,它们必须是二维的。但一般来说,在 Python 中使用列表,其中 MATLAB 使用单元格。 numpy 具有 dtype=object 的数组表现相似,添加多维。

采用对象数组路线,我可以使用 frompyfunc 将此函数应用于列表或数组的元素:

In [231]: np.frompyfunc(np.exp,1,1)([(4,2),(1,2,3)])
Out[231]: 
array([array([ 54.59815003,   7.3890561 ]),
       array([  2.71828183,   7.3890561 ,  20.08553692])], dtype=object)
In [232]: np.frompyfunc(np.exp,1,1)([(4,2),(1,2)])
Out[232]: 
array([[54.598150033144236, 7.3890560989306504],
       [2.7182818284590451, 7.3890560989306504]], dtype=object)

在第 2 种情况下,结果是 (2,2),在第一个 (2,) 形状中。这是因为 np.array([...]) 处理这两个输入的方式。

列表理解同样快,并且可能提供更好的控制。或者至少可以更可预测。