我有一个名为phases
的数组,让我们说它看起来像这样:
phases = numpy.random.uniform(0,1,10)
我现在想要填充一个矩阵,其中每一行都是一个函数f
应用于连续的阶段索引,每列都是它的倍数,看起来像这样:
[[ f(phases[0]) f(2*phases[0]) f(3*phases[0]) ]
[ f(phases[1]) f(2*phases[1]) f(3*phases[1]) ]
... ... ...
[ f(phases[9]) f(2*phases[9]) f(3*phases[9]) ]]
我们可以说f
就像示例一样简单,例如f(x) = x+1
。
所以我认为我只会使用numpy.fromfunction
,如下所示:
numpy.fromfunction(lambda i,j: (j+1)*phases[i]+1,
(phases.size, 3), dtype=float)
但这给了我一个错误:
IndexError: arrays used as indices must be of integer (or boolean) type
如何在i
内访问phases
的{{1}}元素?
或者这是错误的做法?
答案 0 :(得分:4)
numpy.fromfunction
无法正常工作,其文档也具有误导性。
不为每个单元调用该函数,而是对所有索引调用一次。
def fromfunction(function, shape, **kwargs):
dtype = kwargs.pop('dtype', float)
args = indices(shape, dtype=dtype)
return function(*args,**kwargs)
现在,要获得结果,您可以执行以下操作:
In [57]: vf = numpy.vectorize(f)
In [58]: vf(numpy.outer(phases, numpy.arange(1,4)))
Out[58]:
array([[ 1.87176928, 2.74353857, 3.61530785],
[ 1.23090955, 1.4618191 , 1.69272866],
[ 1.29294723, 1.58589445, 1.87884168],
[ 1.05863891, 1.11727783, 1.17591674],
[ 1.28370397, 1.56740794, 1.85111191],
[ 1.87210286, 2.74420573, 3.61630859],
[ 1.08652975, 1.1730595 , 1.25958925],
[ 1.33835545, 1.6767109 , 2.01506634],
[ 1.74479635, 2.48959269, 3.23438904],
[ 1.76381301, 2.52762602, 3.29143903]])
outer
将执行两个向量的外积,正是你想要的除了函数之外。
您的函数必须能够处理数组。对于非平凡的操作,您必须对函数进行矢量化,以便逐个单元地应用它。在您的示例中,您不必关心。
答案 1 :(得分:1)
我认为遵循NumPy惯用法(因此矢量化很好)的最简单方法是首先制作你想要的矩阵,然后将你的函数f
应用到它。
>>> phases = numpy.random.uniform(0,1,10)
>>> phases = phases.reshape((10, 1))
>>> phases = np.tile(phases, (1, 3))
这为您提供了表格
的矩阵(实际上是ndarray
)
[[ phases[0] 2*phases[0] 3*phases[0] ]
[ phases[1] 2*phases[1] 3*phases[1] ]
... ... ...
[ phases[9] 2*phases[9] 3*phases[9] ]]
然后您可以将您的功能应用到。
>>> def f(x):
... return numpy.sin(x)
>>> f(phases)
array([[ 0.56551297, 0.93280166, 0.97312359],
[ 0.38704365, 0.71375602, 0.92921009],
[ 0.62778184, 0.97731738, 0.89368501],
[ 0.0806512 , 0.16077695, 0.23985519],
[ 0.4140241 , 0.75374405, 0.95819095],
[ 0.25929821, 0.50085902, 0.70815838],
[ 0.25399811, 0.49133634, 0.69644753],
[ 0.7754078 , 0.97927926, 0.46134512],
[ 0.53301912, 0.90197836, 0.99331443],
[ 0.44019133, 0.79049912, 0.9793933 ]])
这仅适用于您的函数f
是“向量化”的,也就是说它接受ndarray
并在该数组上按元素操作。如果情况并非如此,那么您可以使用numpy.vectorize
来获取该功能的版本。
>>> import math
>>> def f(x):
... return math.sin(x)
>>> f(phases)
TypeError: only length-1 arrays can be converted to Python scalars
>>> f = numpy.vectorize(f)
>>> f(phases)
array([[ 0.56551297, 0.93280166, 0.97312359],
[ 0.38704365, 0.71375602, 0.92921009],
[ 0.62778184, 0.97731738, 0.89368501],
[ 0.0806512 , 0.16077695, 0.23985519],
[ 0.4140241 , 0.75374405, 0.95819095],
[ 0.25929821, 0.50085902, 0.70815838],
[ 0.25399811, 0.49133634, 0.69644753],
[ 0.7754078 , 0.97927926, 0.46134512],
[ 0.53301912, 0.90197836, 0.99331443],
[ 0.44019133, 0.79049912, 0.9793933 ]])