You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在NumPy或SciPy中实现基于自定义运算符(如异或)的广义克罗内克积?

如何在NumPy或SciPy中实现基于自定义运算符(如异或)的广义克罗内克积?

这个问题问得太实用了!默认的NumPy kron 函数确实只认乘法,但咱们完全可以用NumPy自带的数组操作,轻松实现基于自定义二元运算符的广义克罗内克积,连SciPy都不用额外装~

先从你给出的异或案例入手,一步步拆解实现:

首先先定义你提到的两个布尔数组:

import numpy as np

A = np.asarray([[True,  False],
                [False, False]])

B = np.asarray([[False, True],
                [True,  True]])

针对异或的具体实现

核心思路是:把A扩展成和结果同尺寸的「块重复」结构,把B扩展成对应的「块平铺」结构,然后对两个扩展后的数组直接应用异或运算符。代码如下:

# 把A的每个元素,在行方向重复B的行数,列方向重复B的列数,得到和结果同形状的数组
A_expanded = np.repeat(np.repeat(A, B.shape[0], axis=0), B.shape[1], axis=1)
# 把整个B数组,在行方向平铺A的行数,列方向平铺A的列数,同样得到结果形状
B_expanded = np.tile(B, (A.shape[0], A.shape[1]))
# 直接对两个扩展数组做异或
C = A_expanded ^ B_expanded

运行后得到的C完全符合你想要的结果:

array([[ True, False, False,  True],
       [False, False,  True,  True],
       [False,  True, False,  True],
       [ True,  True,  True,  True]])

推广到任意自定义运算符

如果要支持任意二元运算符(只要它能兼容NumPy数组的广播机制),咱们可以把上面的逻辑封装成一个通用函数:

def generalized_kron(A, B, op):
    """
    实现基于自定义二元运算符的广义克罗内克积
    参数:
        A, B: 输入的NumPy数组
        op: 二元运算符,比如lambda表达式、NumPy内置的元素级函数
    返回:
        广义克罗内克积的结果数组
    """
    A_expanded = np.repeat(np.repeat(A, B.shape[0], axis=0), B.shape[1], axis=1)
    B_expanded = np.tile(B, (A.shape[0], A.shape[1]))
    return op(A_expanded, B_expanded)

比如用这个函数实现异或积,直接传异或的lambda表达式就行:

C = generalized_kron(A, B, lambda a, b: a ^ b)

再举个例子,如果你想做基于加法的广义积(虽然这不是数学上标准的克罗内克积,但作为演示):

# 先把布尔数组转成int类型,不然加法没意义
C_add = generalized_kron(A.astype(int), B.astype(int), lambda a, b: a + b)

更高效的广播优化版

上面的方法需要创建完整的扩展数组,对于大数组来说会占用较多内存。咱们可以用NumPy的新轴扩展+广播技巧,避免显式创建扩展数组,进一步优化内存和速度:

def generalized_kron_broadcast(A, B, op):
    # 给A添加两个新轴,形状从 (m,n) → (m,1,n,1)
    A_bd = A[:, :, np.newaxis, np.newaxis]
    # 给B添加两个新轴,形状从 (p,q) → (1,p,1,q)
    B_bd = B[np.newaxis, :, np.newaxis, :]
    # 广播后两者自动匹配成 (m,p,n,q) 的形状,应用运算符后reshape成最终结果
    return op(A_bd, B_bd).reshape(A.shape[0]*B.shape[0], A.shape[1]*B.shape[1])

用这个函数处理你的异或案例,结果完全一致,但内存占用会低很多——因为广播是动态计算的,不会提前生成完整的中间数组,适合处理大尺寸的数组。

原理说明

不管用哪种方法,核心逻辑都和标准克罗内克积一致:把A的每个元素和整个B数组应用自定义运算符,然后按块拼接成最终结果。我们只是用NumPy的数组操作替代了默认的乘法,换成了你需要的异或(或其他任意运算符)。

备注:内容来源于stack exchange,提问作者Ben

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.14 13:18:03