给定两个 array_like 操作数(而不是尝试广播它们),如何使 ufunc 输出矩阵?
How to make a ufunc output a matrix given two array_like operands (instead of trying to broadcast them)?
我想从 ufunc
中得到两个 ndarray
的值矩阵,例如:
degs = numpy.array(range(5))
pnts = numpy.array([0.0, 0.1, 0.2])
values = scipy.special.eval_chebyt(degs, pnts)
上面的代码不起作用(它给出了 ValueError
因为它试图广播两个数组但失败了,因为它们具有不同的形状:(5,) 和 (3,));我想得到一个值矩阵,其中行对应于度数,列对应于计算多项式的点(反之亦然,这无关紧要)。
目前我的解决方法是简单地使用 for
-loop:
values = numpy.zeros((5,3))
for j in range(5):
values[j] = scipy.special.eval_chebyt(j, pnts)
有办法吗?一般来说,如果你有 n
array_like 个参数,你如何让 ufunc
知道你想要一个 n
维数组?
我知道 numpy.vectorize
,但这看起来既不比简单的 for
循环更快也不优雅(我什至不确定你是否可以将它应用于现有的 ufunc
).
UPDATE 接收 3 个或更多参数的 ufunc
怎么样?尝试 outer
方法给出 ValueError: outer product only supported for binary functions
。例如,scipy.special.eval_jacobi
.
你需要的正是ufuncs的outer方法:
ufunc.outer(A, B, **kwargs)
Apply the ufunc op to all pairs (a, b) with a in A and b in B.
values = scipy.special.eval_chebyt.outer(degs, pnts)
#array([[ 1. , 1. , 1. ],
# [ 0. , 0.1 , 0.2 ],
# [-1. , -0.98 , -0.92 ],
# [-0. , -0.296 , -0.568 ],
# [ 1. , 0.9208, 0.6928]])
更新
更多参数,必须手播。 meshgrid 通常有助于跨越维度中的每个参数。例如:
n=3
alpha = numpy.array(range(5))
beta = numpy.array(range(3))
x = numpy.array(range(2))
data = numpy.meshgrid(n,alpha,beta,x)
values = scipy.special.eval_jacobi(*data)
重塑 broadcasting 的输入参数。在这种情况下,将 degs
的形状更改为 (5, 1) 而不是 (5,)。形状 (5, 1) 与形状 (3,) 一起广播导致形状 (5, 3):
In [185]: import numpy as np
In [186]: import scipy.special
In [187]: degs = np.arange(5).reshape(-1, 1) # degs has shape (5, 1)
In [188]: pnts = np.array([0.0, 0.1, 0.2])
In [189]: values = scipy.special.eval_chebyt(degs, pnts)
In [190]: values
Out[190]:
array([[ 1. , 1. , 1. ],
[ 0. , 0.1 , 0.2 ],
[-1. , -0.98 , -0.92 ],
[-0. , -0.296 , -0.568 ],
[ 1. , 0.9208, 0.6928]])
我想从 ufunc
中得到两个 ndarray
的值矩阵,例如:
degs = numpy.array(range(5))
pnts = numpy.array([0.0, 0.1, 0.2])
values = scipy.special.eval_chebyt(degs, pnts)
上面的代码不起作用(它给出了 ValueError
因为它试图广播两个数组但失败了,因为它们具有不同的形状:(5,) 和 (3,));我想得到一个值矩阵,其中行对应于度数,列对应于计算多项式的点(反之亦然,这无关紧要)。
目前我的解决方法是简单地使用 for
-loop:
values = numpy.zeros((5,3))
for j in range(5):
values[j] = scipy.special.eval_chebyt(j, pnts)
有办法吗?一般来说,如果你有 n
array_like 个参数,你如何让 ufunc
知道你想要一个 n
维数组?
我知道 numpy.vectorize
,但这看起来既不比简单的 for
循环更快也不优雅(我什至不确定你是否可以将它应用于现有的 ufunc
).
UPDATE 接收 3 个或更多参数的 ufunc
怎么样?尝试 outer
方法给出 ValueError: outer product only supported for binary functions
。例如,scipy.special.eval_jacobi
.
你需要的正是ufuncs的outer方法:
ufunc.outer(A, B, **kwargs)
Apply the ufunc op to all pairs (a, b) with a in A and b in B.
values = scipy.special.eval_chebyt.outer(degs, pnts)
#array([[ 1. , 1. , 1. ],
# [ 0. , 0.1 , 0.2 ],
# [-1. , -0.98 , -0.92 ],
# [-0. , -0.296 , -0.568 ],
# [ 1. , 0.9208, 0.6928]])
更新
更多参数,必须手播。 meshgrid 通常有助于跨越维度中的每个参数。例如:
n=3
alpha = numpy.array(range(5))
beta = numpy.array(range(3))
x = numpy.array(range(2))
data = numpy.meshgrid(n,alpha,beta,x)
values = scipy.special.eval_jacobi(*data)
重塑 broadcasting 的输入参数。在这种情况下,将 degs
的形状更改为 (5, 1) 而不是 (5,)。形状 (5, 1) 与形状 (3,) 一起广播导致形状 (5, 3):
In [185]: import numpy as np
In [186]: import scipy.special
In [187]: degs = np.arange(5).reshape(-1, 1) # degs has shape (5, 1)
In [188]: pnts = np.array([0.0, 0.1, 0.2])
In [189]: values = scipy.special.eval_chebyt(degs, pnts)
In [190]: values
Out[190]:
array([[ 1. , 1. , 1. ],
[ 0. , 0.1 , 0.2 ],
[-1. , -0.98 , -0.92 ],
[-0. , -0.296 , -0.568 ],
[ 1. , 0.9208, 0.6928]])