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

如何对Pandas Series中的NumPy数组与DataFrame执行X•Y•X点积运算?

解决Pandas Series中矩阵对应点积运算的问题

我有一个维度为(100,)的Pandas Series对象X,每个元素是形状为(10,10)的NumPy浮点型ndarray;还有一个同样维度为(100,)的Pandas Series对象Y,每个元素是大小为(10,10)的Pandas浮点型DataFrame。X与Y拥有相同的DatetimeIndex类型索引。我想要执行X•Y•X运算,其中“•”表示点积,且方案需能稳健处理NaN值。以下尝试均失败:

date_index = pd.date_range('2022-01-01', periods=100, freq='D')
labels = list('ABCDEFGHIJKLMNOPQRSTUVWXY')
X = pd.Series([np.random.rand(25, 25) for _ in range(100)], index=date_index)
Y = pd.Series([pd.DataFrame(np.random.rand(25, 25), index=labels[:25], columns=labels[:25]) for _ in range(100)], index=date_index)

# Attempt 1:
X.dot(Y).dot(X) ## ValueError: matrices are not aligned

# Attempt 2:
dot_products = lambda x, y: np.dot(np.dot(x, y), x)
X.apply(lambda x: dot_products(x, Y.loc[x])) # ValueError - can't index with multidimensional key

为啥你的尝试失败了?

Attempt 1 报错原因

Pandas自带的Series.dot()是用来计算一维Series的点积(对应元素相乘后求和),并非为处理Series嵌套矩阵设计。调用X.dot(Y)时,Pandas会将整个X、Y当作普通一维数组计算,完全忽略内部矩阵结构,维度自然无法对齐,导致报错。

Attempt 2 报错原因

X.apply(lambda x: ...)中的x是X里的单个NumPy数组元素,不是索引标签。用多维数组去Y.loc[x]索引,不符合Pandas的索引规则,因此触发“can't index with multidimensional key”错误。

正确解决方法

核心逻辑是对X和Y的对应索引元素逐一处理:先将Y中的DataFrame转为NumPy数组,对每组(X[i], Y[i])计算三次矩阵点积,同时将NaN替换为指定值(示例中用0,可按需调整)。

方法1:用zip遍历对应元素

import numpy as np
import pandas as pd

# 给数据加入NaN模拟异常情况
for i in range(10):
    X.iloc[i][np.random.choice(25, 3), np.random.choice(25, 3)] = np.nan
    Y.iloc[i].iloc[np.random.choice(25, 3), np.random.choice(25, 3)] = np.nan

def compute_triple_dot(x_arr, y_df):
    # 将DataFrame转为数组,替换NaN为0
    y_arr = np.nan_to_num(y_df.values, nan=0.0)
    x_arr_clean = np.nan_to_num(x_arr, nan=0.0)
    # 计算X•Y•X的点积
    return np.dot(np.dot(x_arr_clean, y_arr), x_arr_clean)

# 遍历对应元素生成结果Series
result = pd.Series(
    [compute_triple_dot(x, y) for x, y in zip(X, Y)],
    index=date_index
)

方法2:通过索引匹配元素

如果偏好apply写法,可以通过索引来关联X和Y的对应元素:

def compute_with_index(idx):
    x_arr = np.nan_to_num(X.loc[idx], nan=0.0)
    y_arr = np.nan_to_num(Y.loc[idx].values, nan=0.0)
    return np.dot(np.dot(x_arr, y_arr), x_arr)

result = pd.Series(
    [compute_with_index(idx) for idx in X.index],
    index=date_index
)

方法3:用Pandas combine方法简化代码

直接利用combine方法对两个Series的对应元素执行运算:

result = X.combine(Y, lambda x, y: np.dot(np.dot(np.nan_to_num(x, 0), np.nan_to_num(y.values, 0)), np.nan_to_num(x, 0)))

内容的提问来源于stack exchange,提问作者DataScienceNovice

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.22 20:05:34