我无法将列表作为参数传递给numply.apply_along_axis(...)中的func1d。
def test(a, value):
print(value)
return a
a = np.zeros((49), dtype=list)
kwargs = {"value":[1,1,1]}
zep = np.vectorize(test)
np.apply_along_axis(zep, 0, a, **kwargs)
出局:
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/ibpc/osx/lbt/numpy/1.9.2/lib/python3.4/site-packages/nump/lib/shape_base.py", line 91, in apply_along_axis
res = func1d(arr[tuple(i.tolist())], *args, **kwargs)
File "/ibpc/osx/lbt/numpy/1.9.2/lib/python3.4/site-packages/numpy/lib/function_base.py", line 1700, in __call__
return self._vectorize_call(func=func, args=vargs)
File "/ibpc/osx/lbt/numpy/1.9.2/lib/python3.4/site-packages/numpy/lib/function_base.py", line 1769, in _vectorize_call
outputs = ufunc(*inputs)
ValueError: operands could not be broadcast together with shapes (49,) (3,)
所以,他希望我的len(kwargs [“ value”])== 49。但这不是我想要的。 如果需要,我需要更改值(在numpy.apply_along_axis(func1d)中,我需要更新列表)。
如何将列表作为参数传递?或者可以使用另一种方法来解决此问题。
实际上,我在粒子的3D空间中具有一个numpy.array的位置列表。 像这样:
dim = [49,49,49]
dx = 3
origin = [3,3,3]
nb_iter = 5
ntoto=np.load("ntoto.npy")
ntoto = ntoto.flatten()
liste_particles=np.zeros((5), dtype=list)
for i in range(len(liste_particles)):
liste_particles[i]=[[r.uniform(0,150),r.uniform(0,150),r.uniform(0,150)]]*nb_iter #nb_iter is just the number of iteration I want to do in calcTrajs.
vtraj=np.vectorize(calcTrajs, otypes=[list])
np.apply_along_axis(vtraj, 0, liste_particules)
在这里,我有五个随机放置的粒子。此外,我还有另一个numpy.array(shape ==(49,49,49)),其中包含一个vector_field。
这是我需要运行的func1d:
def calcTrajs(a):
global ntoto, dim, dx, origin #ntoto is my vector_field
for b in range(1,len(a)):
ijk = s2g(a[b-1], dx, origin, dim) # function to have on which vector my particle is.(space to grid, because my vector_field is like a grid).
value = np.asarray(ntoto[flatten3Dto1D(ijk, dim[1], dim[2])]) # so value contains the vector who influence my particle.
try:
a[b] = list(a[b-1] + value*1000)
except:
print("error")
break
return a
此函数允许我在vector_field中发射粒子并计算其轨迹。 如您所见,我放入了全局变量。但我想将此变量作为参数而不是全局变量传递。 ntoto是一个numpy.array,dim是一个列表(我的向量字段的维数),dx是单元格的间隔(因为我的vector_field在包含许多单元格的网格中,每个单元格都包含一个向量),并且起点是我的网格。
最诚挚的问候,
亚当
答案 0 :(得分:0)
正如我所评论的,vectorize
或apply...
都不是速度工具。 vectorize
对于相互广播多个阵列很有用。 apply ...
对于迭代2个以上的维度非常有用。只用一两个,就太过分了。两者都是初学者经常滥用的工具。
尽管我尚未测试apply_along_axis
部分,但看起来还可以。错误在于vectorize
中的广播。
尤其是因为您将a
定义为对象dtype,因此应为vectorize
指定类似return dtype的内容。否则,它将执行测试计算以确定它。
In [223]: def test(a, value):
...: print(value)
...: return a
In [224]: zep = np.vectorize(test, otypes=['O'])
In [225]: a = np.array([[1,2,3],[4,5]])
In [226]: a
Out[226]: array([list([1, 2, 3]), list([4, 5])], dtype=object)
zep
与a
和标量一起使用
In [227]: zep(a,1)
1
1
Out[227]: array([list([1, 2, 3]), list([4, 5])], dtype=object)
但是,当a
有2个项目,而value
有3个项目时,我会得到与您相同的错误:
In [228]: zep(a,[1,2,3])
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
<ipython-input-228-382aaa7a2dc6> in <module>()
----> 1 zep(a,[1,2,3])
/usr/local/lib/python3.6/dist-packages/numpy/lib/function_base.py in __call__(self, *args, **kwargs)
2753 vargs.extend([kwargs[_n] for _n in names])
2754
-> 2755 return self._vectorize_call(func=func, args=vargs)
2756
2757 def _get_ufunc_and_otypes(self, func, args):
/usr/local/lib/python3.6/dist-packages/numpy/lib/function_base.py in _vectorize_call(self, func, args)
2829 for a in args]
2830
-> 2831 outputs = ufunc(*inputs)
2832
2833 if ufunc.nout == 1:
ValueError: operands could not be broadcast together with shapes (2,) (3,)
(2,)和(2,)很好:
In [229]: zep(a,['a','b'])
a
b
Out[229]: array([list([1, 2, 3]), list([4, 5])], dtype=object)
(2,)与(2,1)也是,产生(2,2)输出。这是vectoring
可以提供帮助的一种广播示例。
In [230]: zep(a,[['a'],['b']])
a
a
b
b
Out[230]:
array([[list([1, 2, 3]), list([4, 5])],
[list([1, 2, 3]), list([4, 5])]], dtype=object)