参数为numpy的fromfunction

Odd*_*ing 25 python arrays numpy

我还没有弄清楚关键概念numpy.

我想创建一个三维数组,并使用函数调用的结果填充每个单元格 - 即该函数将使用不同的索引多次调用并返回不同的值.

注意:自编写此问题以来,文档已更新为更清晰.

我可以用零(或空)创建它,然后使用for循环覆盖每个值,但直接从函数填充它似乎更干净.

fromfunction听起来很完美.阅读文档听起来像每个单元格调用一次函数.

但是当我真正尝试它的时候......

from numpy import *

def sum_of_indices(x, y, z):
    # What type are X, Y and Z ? Expect int or duck-type equivalent.
    # Getting 3 individual arrays
    print "Value of X is:"
    print x

    print "Type of X is:", type(x)
    return x + y + z

a = fromfunction(sum_of_indices, (2, 2, 2))
Run Code Online (Sandbox Code Playgroud)

我希望得到类似的东西:

Value of X is:
0
Type of X is: int
Value of X is:
1
Type of X is: int
Run Code Online (Sandbox Code Playgroud)

重复4次.

我明白了:

Value of X is:
[[[ 0.  0.]
  [ 0.  0.]]

 [[ 1.  1.]
  [ 1.  1.]]]
[[[ 0.  0.]
  [ 1.  1.]]

 [[ 0.  0.]
  [ 1.  1.]]]
[[[ 0.  1.]
  [ 0.  1.]]

 [[ 0.  1.]
  [ 0.  1.]]]
Type of X is: <type 'numpy.ndarray'>
Run Code Online (Sandbox Code Playgroud)

该函数只调用一次,并且似乎返回整个数组.

基于对索引函数的多次调用来填充数组的正确方法是什么?

小智 32

在这方面,文件非常误导.就像你注意到的那样:f(0,0), f(0,1), f(1,0), f(1,1)numpy 不是表演,而是表演

f([[0., 0.], [1., 1.]], [[0., 1.], [0., 1.]])
Run Code Online (Sandbox Code Playgroud)

当你尝试使用类似的东西时,使用ndarrays而不是承诺的整数坐标是非常令人沮丧的lambda i: l[i],其中l是另一个数组或列表(尽管如此,在numpy中可能有更好的方法).

numpy vectorize函数解决了这个问题.你在哪里

m = fromfunction(f, shape)
Run Code Online (Sandbox Code Playgroud)

尝试使用

g = vectorize(f)
m = fromfunction(g, shape)
Run Code Online (Sandbox Code Playgroud)

  • [`vectorize`的 NumPy 文档](https://docs.scipy.org/doc/numpy-1.15.0/reference/ generated/numpy.vectorize.html#numpy.vectorize) 说:_输出的数据类型矢量化的值是通过使用输入的第一个元素调用函数来确定的。这可以通过指定“otypes”参数来避免。_ (2认同)

Odd*_*ing 18

我显然没有说清楚.我得到的答案fromfunc实际上正如我的测试代码所示,我已经知道了,因为我的测试代码证明了这一点.

我正在寻找的答案似乎分为两部分:


fromfunc文件具有误导性.它可以立即填充整个数组.

注意:自编写此问题以来,文档已更新为更清晰.

特别是,文档中的 这一行不正确的(或者至少是误导性的)

例如,如果shape是(2,2),那么参数又是(0,0),(0,1),(1,0),(1,1).

不.如果shape(即从上下文,第二个参数fromfunction)是(2,2),参数将是(不是"轮流",而是在唯一的调用中):

(array([[ 0.,  0.], [ 1.,  1.]]), array([[ 0.,  1.], [ 0.,  1.]]))
Run Code Online (Sandbox Code Playgroud)

文档已更新,目前读取更准确:

使用N个参数调用该函数,其中N是形状的等级.每个参数表示沿特定轴变化的阵列的坐标.例如,如果形状是(2,2),那么参数将是数组([[0,0],[1,1]])和数组([[0,1],[0,1]])

(我的简单示例,源自手册中的示例,可能具有误导性,因为+可以对数组和索引进行操作.这种模糊性是文档不清楚的另一个原因.我想最终使用不是的函数基于数组,但是基于单元格 - 例如,可以基于索引从URL或数据库获取每个值,甚至可以从用户输入.)


回到问题 - 我如何从每个元素调用一次的函数填充数组,答案似乎是:

你不能以功能的方式做到这一点.

你可以用命令式/迭代式的方式来做 - 即编写嵌套的for循环,并自己管理索引长度.

您也可以将其作为迭代器,但迭代器仍需要跟踪自己的索引.

  • 这是一个令人难以置信的误导性文档.再加上这个事实,`x == y`有完全荒谬的做逐点比较和返回数组的行为,你有文档的例子,实际上似乎暗示,对于有经验以外的经验的人,它正在做细胞逐个单元计算 (10认同)

Dan*_*iel 6

我认为你误解了什么fromfunction

numpy 源代码

def fromfunction(function, shape, **kwargs):
    dtype = kwargs.pop('dtype', float)
    args = indices(shape, dtype=dtype)
    return function(*args,**kwargs)
Run Code Online (Sandbox Code Playgroud)

Whereindicesmeshgrid每个变量所在的位置相当np.arange(x)

>>> side = np.arange(2)
>>> side
array([0, 1])
>>> x,y,z = np.meshgrid(side,side,side)
>>> x
array([[[0, 0],
        [1, 1]],

       [[0, 0],
        [1, 1]]])
>>> x+y+z #Result of your code.
array([[[0, 1],
        [1, 2]],

       [[1, 2],
        [2, 3]]])
Run Code Online (Sandbox Code Playgroud)