【问题标题】:Apply function to every matrix of numpy array将函数应用于 numpy 数组的每个矩阵
【发布时间】:2019-06-03 11:57:25
【问题描述】:

我想对我的 (6890,6890,3,3) numpy 数组中的每个 3x3 矩阵应用一个函数。到目前为止,我已经尝试在一个较小的示例中使用矢量化,并使用一个更简单的函数,但没有成功。

def myfunc(x):
    return np.linalg.norm(x)

m = np.arange(45).reshape(5,3,3)
t = m.shape[0]
r = np.zeros((t, t))

q = m[:,None,...] @ m.swapaxes(1,2) # m[i] @ m[j].T
f = np.vectorize(q, otypes=[np.float])
res = myfunc(f)

矢量化甚至是有效解决此问题的正确方法还是我应该尝试其他方法?我也研究了numpy.apply_along_axis,但这仅适用于一维子数组。

【问题讨论】:

  • 列出的myfunc 是您正在使用的实际功能吗?
  • 不,不是。这是实际的:pyquaternion.Quaternion.log(pyquaternion.Quaternion(matrix=m)).norm
  • 如果你的函数只能使用 3x3 数组,那么调用 6890*6890 次是没有办法的。
  • np.vectorize 将很难应用,而且速度较慢。 `apply_along 并不容易。
  • np.vectorize 有一个注释说它不承诺任何加速。此外,它通常将标量元素传递给您的函数,而您想要传递 2d 元素。它有一个signature 模式可以做到这一点,但速度更慢。

标签: python arrays numpy vectorization


【解决方案1】:

你需要遍历每个元素并应用函数:

import numpy as np

# setup function
def myfunc(x):
    return np.linalg.norm(x*2)

# setup data array
data = np.arange(45).reshape(5, 3, 3)

# loop over elements and update
for item in np.nditer(data, op_flags = ['readwrite']):
    item[...] = myfunc(item)

如果您需要整个 3x3 数组的应用函数,请使用:

out_data = []
for item in data:
    out_data.append(myfunc(item))

输出:

[14.2828568570857, 39.761790704142086, 66.4529909033446, 93.32202312423365, 120.24974012445931]

【讨论】:

  • 如果我想将该函数应用于我的实际 (6890,6890,3,3) 数组中的所有 6890*6890 3x3 矩阵,我是否必须引入一个嵌套的 for 循环(使用 6890* 6890 次迭代)?因为这正是我想要避免的,因为它太慢了。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-04-08
  • 2013-02-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-11-23
相关资源
最近更新 更多