【问题标题】:How do I create a numpy recarray of arbitrary functions?如何创建任意函数的 numpy 重新数组?
【发布时间】:2015-04-29 23:09:35
【问题描述】:

我正在创建一个numpy.recarray,如下所示:

import numpy as np

arr = np.array((1., 2.), dtype = [('alpha', np.float, 'beta', np.float)])
arr = np.view(np.recarray)

如果不是 np.floats alphabeta 引用任意函数,我该怎么做?

【问题讨论】:

  • dtype 是任意函数意味着什么?如果其中一个 dtype 是 print(使用 from __future__ import print_function 将其作为函数),您希望发生什么,以及您将如何与生成的数组进行交互?
  • 另外,这不是recarray。
  • 在这种情况下,可以通过arr.print 访问print 功能,例如通过arr.print('foo') 将'foo' 打印到屏幕上,这是我在这里需要的唯一功能。
  • 我不明白你为什么要为此使用recarray。
  • 我同意这看起来不太合乎逻辑。简而言之,我有一些代码正在尝试修改以满足我的需要。不幸的是,最后一位编码员似乎很喜欢np.recarray(或任何这些构造)......很多而且碰巧如果我可以使用np.recarray获得这个功能,它将节省我重新编写大量代码.. .

标签: python arrays function numpy


【解决方案1】:

np.object dtype 可以包含任何 Python 对象,包括函数。

例如:

import numpy as np

lmb = lambda: "help, I'm trapped in an array!"
arr = np.array([(max, lmb)], dtype=[('alpha', np.object), ('beta', np.object)])
arr = arr.view(np.recarray)

print(repr(arr))
# array([(<built-in function max>, <function <lambda> at 0x63992a8>)], 
#       dtype=[('alpha', 'O'), ('beta', 'O')]).view(numpy.recarray)

print(arr.alpha[0](1, 2))
# 2

print(arr.beta[0]())
# help, I'm trapped in an array!

在函数元组周围添加了一组额外的方括号,以强制数组是一维的,这允许您索引第一行以访问它包含的函数。

如果允许数组是 0 维的,访问函数会有点尴尬,但它仍然是可能的,正如 user2357112 在下面的 cmets 中指出的那样:

arr2 = np.array((max, lmb), dtype=[('alpha', np.object), ('beta', np.object)])
arr2 = arr2.view(np.recarray)

print(repr(arr2))
# array((<built-in function max>, <function <lambda> at 0x63995f0>), 
#       dtype=[('alpha', 'O'), ('beta', 'O')]).view(numpy.recarray)

print(repr(arr2['alpha']))
# array(<built-in function max>, dtype=object)

# we can't access the function without any indexing, because `arr2['alpha']` 
# is still an ndarray containing a function, rather than a plain function,
# and arrays have no `.__call__()` method:

arr2.alpha(1, 2)
# ---------------------------------------------------------------------------
# TypeError                                 Traceback (most recent call last)
# <ipython-input-100-dc1bd6446de4> in <module>()
# ----> 1 arr2['alpha'](1, 2)

# TypeError: 'numpy.ndarray' object is not callable

# it is possible to access the function by indexing with an empty tuple
print(arr2.alpha[()](1, 2))
# 2

我在此处修复了您的示例中的其他几个语法问题。

  • dtype= 参数应该为每个字段包含一个单独的 (name, dtype) 元组,而不是单个长元组。

  • .view 是 ndarray 的方法,而不是独立函数。

不过,我不得不问你为什么要这样做。一个简单的dict 似乎是一个更合适的数据结构。

【讨论】:

  • "好像有必要先创建空数组,然后用函数填写字段。" - 这可能与您正在创建长度为 1 的一维数组的事实有关,而原始代码似乎创建了一个 0 维数组。
  • @user2357112 是的,实际上需要创建一个一维数组才能调用该函数(请参阅我的更新)
  • 不完全;您可以使用 0 维数组和 arr.alpha[()]arr.alpha[...] 而不是 arr.alpha[0] 获得相同的效果。
  • 好点,虽然arr2.alpha[...] 不起作用,因为它还返回一个数组而不是它包含的函数
  • 什么 - 我可以发誓 [...] 应该进行转换,但看起来只有 [()] 可以完成这项工作。我记得之前尝试过 [...] 并让它工作过。
【解决方案2】:

根据 cmets 中的说明,这听起来不像是重新排列的工作。在 Python 3 中,您需要 types.SimpleNamespace;在 Python 2 中,您可以很容易地自己实现它:

class Namespace(object):
    def __init__(self, **kwargs):
        self.__dict__.update(kwargs)

namespace = Namespace(func1=print, func2=len, func3=sum)

namespace.func1(namespace.func2([1, 2])) # prints 2

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-12-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-06-11
    • 2023-03-12
    相关资源
    最近更新 更多