调用np.log时报ufunc循环不支持numpy.ndarray参数的问题排查
报错原因
你构造动态矩阵e时的写法存在维度问题:
- 当
t是长度为98的一维数组时,直接写np.array([[1-t, t], [0.03, 0.97]])不会生成「每个t值对应一个2×2矩阵」的三维数值数组,而是会生成dtype为object的二维数组:数组的4个位置分别存了长度为98的数组1-t、长度为98的数组t、标量0.03、标量0.97,属于嵌套结构,不是规则的数值矩阵。 - 对object类型数组做
np.log运算时,numpy会尝试调用数组内每个元素自带的.log()方法,而存放在e里的元素是普通ndarray和标量,没有这个方法,就触发了你看到的报错。你单独测试np.log(t)能正常运行,是因为t本身是纯数值的一维数组,不存在object嵌套的问题。
修复方案
核心是把所有矩阵的维度对齐,构造规则的三维数值数组(第一维对应t的不同取值,后两维对应单个t下的2×2矩阵),再调整求和逻辑保留t对应的结果维度即可:
- 构造
e时用np.stack拼接生成形状为(len(t), 2, 2)的三维数值数组,避免生成object数组 - 矩阵乘法会自动通过广播适配批量维度,不需要修改固定矩阵f/r/d/c的写法
- 聚合求和时指定
axis=(1,2),只对矩阵对应的两个维度求和,保留每个t对应的计算结果,不要直接用无参数的np.sum把所有值加总成单个标量
修复后可正常运行的代码如下:
import numpy as np import matplotlib.pyplot as plt t = np.arange(0.01, 0.99, 0.01) len_t = len(t) f = np.array([[0.35, 0.65]]) # 生成形状为(98,2,2)的规则三维数值矩阵 e = np.stack([ np.stack([1 - t, t], axis=1), np.repeat(np.array([[0.03, 0.97]]), len_t, axis=0) ], axis=1) r = np.array([[0.95, 0.05], [0.06, 0.94]]) d = np.array([[0.99, 0.01], [0.08, 0.92]]) c = np.array([[0, 1], [1, 0]]) # 沿批量维度计算,保留每个t对应的D值 D = np.sum(f @ (e @ r @ d * c), axis=(1, 2)) u = f @ e # 沿批量维度计算,保留每个t对应的I值 I = np.sum(f @ (e * np.log(e / u)), axis=(1, 2)) plt.plot(t, D, label='D') plt.plot(t, I, label='I') plt.xlabel('t') plt.legend() plt.show()
代码验证:当t=0.08时,e的第一行值为[0.92, 0.08],和你最初固定矩阵的代码参数完全一致,计算得到的D、I值和你之前的输出0.14538525、0.45687371996485304完全匹配,计算逻辑正确。
内容的提问来源于stack exchange,提问作者SYD
相关产品推荐
相关产品推荐

