【问题标题】:using numpy fromfunction to fill a matrix with a custom function使用 numpy fromfunction 用自定义函数填充矩阵
【发布时间】:2020-06-26 08:18:52
【问题描述】:

这与another question I have 有关,但我正在寻找矢量化/广播解决方案。

我希望在这里尝试使用np.fromfunction,但遇到了问题。

MWE 是

# L1 and L2 will range from 0 to 3 typically, sometimes up to 5
# all of the following are dummy values but match correct `type`
L1, L2, x1, x2, fac = 2, 3, 2.0, 4.5, 2.3
saved_values = np.random.uniform(high=75.0, size=[max(L1,L2) + 1, max(L1,L2) + 1]) 
facts = np.random.uniform(high=65.0, size=[L1 + L2 + 1])
val = 0

for i in range(L1+1):
    sf = saved_values[L1][i] * x1 ** (L1 - i)
    for j in range(L2 + 1):
        m = i + j
        if m % 2 == 0:
            num = sf * facts[m] / (2 * fac) ** (m / 2)
            val += saved_values[L2][j] * x1 ** (L1 - j) * num

我想使用np.fromfunction 用必要的值填充矩阵,而不是使用未矢量化且可能较慢(矢量化对我来说更重要)的双循环

我尝试了以下

matrix = np.fromfunction(lambda i, j:
                         saved_values[L1][i] * x1 ** (L1 - i) *
                         saved_values[L2][j] * x2 ** (L2 - j) *
                         facts[i+j] / (2 * fac) **( (i+j) / 2),
                         (L1+1,L2+1)
                         )

这会生成双 for 循环矩阵,然后我需要检查它并使任何会失败的 (i+j) % 2 == 0 具有零值,然后对矩阵中的所有元素求和。

然而

我收到以下错误

Traceback (most recent call last):                                                                                                                                                 
  File "main.py", line 54, in <module>                                                                                                                                             
    (L1+1,L2+1)                                                                                                                                                                    
  File "/usr/lib/python3/dist-packages/numpy/core/numeric.py", line 1808, in fromfunction                                                                                          
    return function(*args,**kwargs)                                                                                                                                                
  File "main.py", line 53, in <lambda>                                                                                                                                             
    facts[i+j] / (2 * fac) **( (i+j) / 2),                                                                                                                                         
IndexError: arrays used as indices must be of integer (or boolean) type

【问题讨论】:

  • fromfunction 不会“矢量化”。当你遇到这样的问题时,写一个小函数来告诉你i,j实际上是什么。

标签: python-3.x numpy numpy-ufunc


【解决方案1】:

我想,你认为函数作为第一个参数传递 对于每个组合,to np.fromfunction 被调用 几次ij

不幸的是,事实并非如此。查看实际的方式 它运行,做这样的实验:

def myFun(i, j):
    print(f'myFun:\n{i.shape}\n{i}\n{j.shape}\n{j}')
    rv = i + j
    return rv

我特意把痕迹打印出来,以表明我的意思。

然后运行它:

np.fromfunction(myFun, (2, 3))

结果是:

myFun:
(2, 3)
[[0. 0. 0.]
 [1. 1. 1.]]
(2, 3)
[[0. 1. 2.]
 [0. 1. 2.]]

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

第一部分是打印输出,只出现一次,第二部分 - 实际结果。请注意:

  • ij的形状都是(2,3),
  • ij 实际上都是数组,而不是整数,
  • 整个计算是通过两个数组相加来完成的。

所以结论是:

  • 传递的函数以矢量化方式运行, 在参数数组上,添加相应的元素和 返回结果,
  • 您的概念可能无法实现。

【讨论】:

  • 我不能只创建一个依赖于 i、j 的任意 myfunc 以及一个其索引使用 i、j 的数组,然后这样做吗?
  • 是的,你可以。但是这个函数必须在 2 个嵌套循环中调用,而不是使用 np.fromfunction
  • 我不能使用循环。这里的一切都是标量,但真正的问题是向量。我正在尝试摆脱for loops,以便我有一个可以传递数组的矢量化解决方案。即,m % 2 == 0 会破坏向量化,for 循环本身也一样,因为它们具有 range(L1+1) 等。也就是说,我需要评估传递向量的 xyz 分量的循环。目前设置为仅传递 1 个维度。
猜你喜欢
  • 2018-09-20
  • 1970-01-01
  • 2019-09-22
  • 2023-04-06
  • 1970-01-01
  • 2010-12-14
  • 2019-06-15
  • 2019-04-17
  • 2015-08-12
相关资源
最近更新 更多