Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/313.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python numpy'的参数;Froms函数_Python_Arrays_Numpy - Fatal编程技术网

Python numpy'的参数;Froms函数

Python numpy'的参数;Froms函数,python,arrays,numpy,Python,Arrays,Numpy,我还没有摸索过numpy中的关键概念 我想创建一个三维数组,并用函数调用的结果填充每个单元格,也就是说,函数将使用不同的索引多次调用,并返回不同的值 注意:自撰写此问题以来,文档已更新为更清晰。 我可以用零(或空)创建它,然后用for循环覆盖每个值,但直接从函数填充它似乎更干净 听起来很完美。听起来好像每个单元格调用一次函数 但当我真的尝试的时候 from numpy import * def sum_of_indices(x, y, z): # What type are X, Y

我还没有摸索过
numpy
中的关键概念

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

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

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

听起来很完美。听起来好像每个单元格调用一次函数

但当我真的尝试的时候

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))
我希望得到如下结果:

Value of X is:
0
Type of X is: int
Value of X is:
1
Type of X is: int
重复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'>
X的值为:
[[[ 0.  0.]
[ 0.  0.]]
[[ 1.  1.]
[ 1.  1.]]]
[[[ 0.  0.]
[ 1.  1.]]
[[ 0.  0.]
[ 1.  1.]]]
[[[ 0.  1.]
[ 0.  1.]]
[[ 0.  1.]
[ 0.  1.]]]
X的类型为:
该函数只调用一次,并且似乎返回整个数组作为结果


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

我认为您误解了函数
的功能

numpy

其中
索引
相当于
网格
,其中每个变量都是
np.arange(x)


这会给你一个错误的结果吗
a
应该和预期的一样(在我测试它时也是如此),并且似乎是一种很好的方法来做你想做的事情

>>> a
array([[[ 0.,  1.],    # 0+0+0, 0+0+1
        [ 1.,  2.]],   # 0+1+0, 0+1+1

       [[ 1.,  2.],    # 1+0+0, 1+0+1
        [ 2.,  3.]]])  # 1+1+0, 1+1+1
由于
fromfunction
对输入的数组索引起作用, 您可以看到它只需要调用一次。文档中没有明确说明这一点,但是您可以看到该函数是在源代码中的索引数组上调用的(从
numeric.py
):

对数组输入调用索引之和,其中每个数组保存该索引的索引值 维度

array([[[ 0.,  0.],
        [ 1.,  1.]],

       [[ 1.,  1.],
        [ 1.,  1.]]])

+

array([[[ 0.,  0.],
        [ 1.,  1.]],

       [[ 0.,  0.],
        [ 1.,  1.]]])

+
array([[[ 0.,  1.],
        [ 0.,  1.]],

       [[ 0.,  1.],
        [ 0.,  1.]]])

=

array([[[ 1.,  1.],
        [ 1.,  2.]],

       [[ 1.,  2.],
        [ 2.,  3.]]])

我显然没有说清楚。我得到的响应是
fromfunc
实际上可以像我的测试代码所演示的那样工作,我已经知道了这一点,因为我的测试代码演示了它

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


fromfunc
文档具有误导性。它可以一次填充整个阵列

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

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

例如,如果
shape
为(2,2),那么参数依次为(0,0)、(0,1)、(1,0)、(1,1)

否。如果
shape
(即从上下文,
fromfunction
)的第二个参数为(2,2),则参数为(不是“依次”,而是在唯一调用中):

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

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

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


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

您不能在功能性样式中执行此操作

您可以以命令式/迭代式的方式完成这项工作,即编写嵌套循环,并自行管理索引长度

您也可以作为迭代器来执行,但迭代器仍然需要跟踪自己的索引。

文档在这方面非常误导。正如您所注意到的:numpy执行的不是
f(0,0),f(0,1),f(1,0),f(1,1)

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

numpy
vectorize
函数解决了这个问题

m = fromfunction(f, shape)
试用

g = vectorize(f)
m = fromfunction(g, shape)

以下是我对您问题的看法:

正如Chris Jones所提到的,解决方案的核心是使用
np.vectorize

# Define your function just like you would
def sum_indices(x, y, z):
    return x + y + z

# Then transform it into a vectorized lambda function
f = sum_indices
fv = np.vectorize(f)
如果现在执行
np.fromfunction(fv,(3,3,3))

array([[[0., 1., 2.],
        [1., 2., 3.],
        [2., 3., 4.]],

       [[1., 2., 3.],
        [2., 3., 4.],
        [3., 4., 5.]],

       [[2., 3., 4.],
        [3., 4., 5.],
        [4., 5., 6.]]])

这就是你想要的吗?

我认为fromfunction的大多数示例都使用方形数组有点令人困惑

也许查看非方形阵列会有所帮助

def f(x,y):
    print(f'x=\n{x}')
    print(f'y=\n{y}')
    return x+y

z = np.fromfunction(f,(4,3))
print(f'z=\n{z}')
结果:

x=
[[0 0 0]
 [1 1 1]
 [2 2 2]
 [3 3 3]]
y=
[[0 1 2]
 [0 1 2]
 [0 1 2]
 [0 1 2]]
z=
[[0 1 2]
 [1 2 3]
 [2 3 4]
 [3 4 5]]

如果将参数
dtype
设置为
int
,则可以获得所需的输出:

a=fromfonment(索引的总和,(2,2,2),dtype=int)


您的预期结果是什么?每个单元格调用一次fromfunction-您所说的“对索引函数的多次调用”是什么意思?在您的第一个代码块中,
a
是填充的数组,其中
a[i,j,k]=索引(i,j,k)的和
对不起,我认为从评论中可以清楚地看到预期结果。我已经展开了。是的,我知道“a”是填充的数组,但(我相信)只是因为数组添加。当我用“实”函数(例如数据库查找)替换索引的和时,这是不可能的。明白(现在),但请参见我的答案。文档与此代码不匹配,这并没有解决正确的方法是什么的问题。抱歉,我的示例将您引入了错误的路径。是的,examp
# Define your function just like you would
def sum_indices(x, y, z):
    return x + y + z

# Then transform it into a vectorized lambda function
f = sum_indices
fv = np.vectorize(f)
array([[[0., 1., 2.],
        [1., 2., 3.],
        [2., 3., 4.]],

       [[1., 2., 3.],
        [2., 3., 4.],
        [3., 4., 5.]],

       [[2., 3., 4.],
        [3., 4., 5.],
        [4., 5., 6.]]])
def f(x,y):
    print(f'x=\n{x}')
    print(f'y=\n{y}')
    return x+y

z = np.fromfunction(f,(4,3))
print(f'z=\n{z}')
x=
[[0 0 0]
 [1 1 1]
 [2 2 2]
 [3 3 3]]
y=
[[0 1 2]
 [0 1 2]
 [0 1 2]
 [0 1 2]]
z=
[[0 1 2]
 [1 2 3]
 [2 3 4]
 [3 4 5]]