假设我在Python中有一个非常基本的功能:
def f(x, y):
return x + y
然后我可以用标量,f(1, 5.4) == 6.4
或任意(但相同)形状的numpy向量来调用它。例如。这有效:
x = np.arange(3)
y = np.array([1,4,2.3])
f(x, y)
给出一个包含条目1,5,4.3的数组。
但如果f更复杂怎么办?例如,xx
和yy
在这里是1D numpy数组。
def g(x, y):
return np.sum((xx - x)**2 + (yy - y)**2)
(我赶紧补充一点,我对这个特定 g
不感兴趣,但在一般策略中...)然后g(5, 6)
工作正常,但如果我想要传递numpy数组,我似乎必须用明确的广播等编写一个非常不同的函数。例如:
def gg(x, y):
xfull = np.stack([x]*len(xx),axis=-1)
yfull = np.stack([y]*len(xx),axis=-1)
return np.sum((xfull - xx)**2 + (yfull - yy)**2, axis=-1)
现在可以使用标量和数组。但它看起来像一团糟,很难读懂。
有更好的方法吗?
答案 0 :(得分:1)
假设:
x
我的第一个问题是:
y
和xx
写的?yy
和xx
是什么?你说1d数组。相同的长度?yy
和x
按固定金额抵消,并取其正方形的总和,返回单个值?我的下一步是探索广播'这个表达的极限。例如,它适用于xx-x
中可以使用的任何xx
。这可能是一个0d数组,一个元素1d数组,一个形状与g(1,2)
g(xx,xx)
g(xx[:,None],yy[None,:])
相同的数组,或者其他任何可以广播的数组。用`xx。这是对广播'的透彻理解的地方。是至关重要的。
xx-xx[:,None]
np.sum
虽然产生了一个二维数组。所写的gg
取所有值的总和,即扁平化。您的g
建议您想要在最后一个轴上求和。如果是这样,请将其放在def g(x, y):
return np.sum((xx - x)**2 + (yy - y)**2, axis=-1)
stack
您在gg
中使用In [101]: xx
Out[101]: array([0, 1, 2, 3, 4])
In [103]: np.stack([np.arange(3)]*len(xx), axis=-1)
Out[103]:
array([[0, 0, 0, 0, 0],
[1, 1, 1, 1, 1],
[2, 2, 2, 2, 2]])
会产生:
x[:,None]
我会把它写成In [104]: xx-_
Out[104]:
array([[ 0, 1, 2, 3, 4],
[-1, 0, 1, 2, 3],
[-2, -1, 0, 1, 2]])
In [105]: xx-np.arange(3)[:,None]
Out[105]:
array([[ 0, 1, 2, 3, 4],
[-1, 0, 1, 2, 3],
[-2, -1, 0, 1, 2]])
x
这不适用于标量xx-np.asarray(x)[...,None]
;但这确实
np.array
np.asarray
或numpy
通常用作...
函数的开头,以容纳标量或列表输入。处理可变数量的维度时,reshape(...,-1)
非常方便。 [...,None]
和numpy
广泛用于扩展或概括维度。
通过查看 function parsejson(data) {
var temp2 = new Array();
if (data) {
$.each(data, function (i, val) {
vproductid = data[i].productid;
vproductname = data[i].product_name;
vexpirydt = data[i].expiry;
temp2.push({vproductid,vproductname,vexpirydt});
});
console.log([temp2]);
return [temp2];
}
}
函数的Python代码,我学到了很多东西。我也从多年的MATLAB工作中学到了关于尺寸的迂腐。跟踪预期和实际的阵列形状。它有助于使用突出错误的测试形状。用(2,3)数组测试而不是模糊(3,3)数组。