首页 > 解决方案 > 更快的 3D 矩阵运算 - Python

问题描述

我正在使用 Python 中的 3D 矩阵,例如,给定这样的矩阵,大小为 2x3x4:

[[[1 2 1 4]
  [3 2 1 1]
  [4 3 1 4]]

 [[2 1 3 3]
  [1 4 2 1]
  [3 2 3 3]]]

我的任务是在每个维度矩阵的每一行中找到熵值。例如,在上面矩阵的第 1 维的第 1 行中[1,2,1,4],归一化值(因此总和为 1)是[0.125, 0.25, 0.125, 0.5],熵的值由公式计算,-sum(i*log(i))其中 i 是归一化值。生成的矩阵是一个 2x3 矩阵,其中每个维度有 3 个熵值(因为有 3 行)。

这是我每次使用随机矩阵的代码的工作示例:

from scipy.stats import entropy
import numpy as np

matrix = np.random.randint(low=1,high=5,size=(2,3,4)) #how if size is (200,50,1000)
entropy_matrix=np.zeros((matrix.shape[0],matrix.shape[1]))
for i in range(matrix.shape[0]):
    normalized = np.array([float(k)/np.sum(j) for j in matrix[i] for k in j]).reshape(matrix.shape[1],matrix.shape[2])
    entropy_matrix[i] = np.array([entropy(m) for m in normalized])

我的问题是如何扩大这个程序以使用非常大的 3D 矩阵(例如大小为 200x50x1000)?

我在 Windows 10 中使用 Python(带有 Anaconda 发行版)。使用 200x50x1000 的 3D 矩阵大小,我的计算机上的运行时间为 290 秒。

标签: pythonnumpymatrixvectorscipy

解决方案


使用entropy第二部分的定义和第一部分的广播操作,一个矢量化解决方案将是 -

p1 = matrix/matrix.sum(-1,keepdims=True).astype(float)
entropy_matrix_out = -np.sum(p1 * np.log(p1), axis=-1)

或者,我们可以einsum将第二部分用于进一步的性能。促进 -

entropy_matrix_out = -np.einsum('ijk,ijk->ij',p1,np.log(p1),optimize=True)

推荐阅读