1

我有一个协方差矩阵的时间序列存储为 MultiIndex(我们称之为“A”)和一个标量的时间序列存储为 DataFrame(我们称之为“b”)。

“A”的形状为“k”x“n”x“n”,“b”的形状为“k”x“n”,所以我有一个“k”日期的协方差矩阵的MultiIndex,形状为“n” x“n”,我想乘以标量的“k”x“n”x 1 DataFrame 以获得“k”x“n”x 1 DataFrame。

当我尝试 A.multiply(b) 之类的方法时,它不起作用,因为 MultiIndex 维度是 (kxn, n) 并且不严格匹配 (k, n) 的 DataFrame 维度。

我能够使用列表理解执行计算并将 MultiIndex 和 DataFrame 转换为 numpy 数组,但这需要非常非常长的时间,所以我必须非常低效地执行此操作。

这方面的一个例子是:

[np.dot( np.array( A.loc[timestamp,:] ), np.array( b.loc[timestamp,:] ) ) for timestamp in b.index]

这需要非常长的时间来计算。有没有一种快速的方法来执行这个计算?

4

1 回答 1

2

A这是大小为5×3×3 和5×3的随机值数据帧b

>>> A
                              0         1         2
2021-08-14 11:14:00 0  0.309559  0.286455  0.080467
                    1  0.996128  0.666138  0.354322
                    2  0.113316  0.208389  0.197855
2021-08-14 11:15:00 0  0.299459  0.650561  0.481504
                    1  0.570308  0.298572  0.677013
                    2  0.476066  0.610945  0.750575
2021-08-14 11:16:00 0  0.861801  0.692752  0.046450
                    1  0.587891  0.389874  0.779039
                    2  0.009947  0.647356  0.735746
2021-08-14 11:17:00 0  0.990027  0.185747  0.286276
                    1  0.831238  0.474372  0.459076
                    2  0.885953  0.768626  0.866064
2021-08-14 11:18:00 0  0.952294  0.106072  0.477348
                    1  0.370116  0.646081  0.873394
                    2  0.439066  0.568404  0.227528
>>> b
                            0         1         2
2021-08-14 11:14:00  0.113316  0.208389  0.197855
2021-08-14 11:15:00  0.476066  0.610945  0.750575
2021-08-14 11:16:00  0.009947  0.647356  0.735746
2021-08-14 11:17:00  0.885953  0.768626  0.866064
2021-08-14 11:18:00  0.439066  0.568404  0.227528

如果要将每一行乘以A的单个值b,即b列应与第二级A索引对齐,则应使用stack

>>> A.mul(b.stack(), axis='index')
                              0         1         2
2021-08-14 11:14:00 0  0.035078  0.032460  0.009118
                    1  0.207582  0.138816  0.073837
                    2  0.022420  0.041231  0.039147
2021-08-14 11:15:00 0  0.142562  0.309710  0.229227
                    1  0.348427  0.182411  0.413618
                    2  0.357323  0.458560  0.563363
2021-08-14 11:16:00 0  0.008572  0.006891  0.000462
                    1  0.380575  0.252387  0.504315
                    2  0.007318  0.476290  0.541322
2021-08-14 11:17:00 0  0.877118  0.164563  0.253627
                    1  0.638911  0.364615  0.352858
                    2  0.767292  0.665679  0.750067
2021-08-14 11:18:00 0  0.418120  0.046573  0.209587
                    1  0.210376  0.367235  0.496441
                    2  0.099900  0.129328  0.051769

另一方面,如果您希望b列与列对齐A,您可以使用pd.DataFrame.align(),它返回两个数据框的对齐版本。此处A将与 确认的一样保持不变.compare(),并且b_aligned将在每个二级索引中重复其行以匹配A的索引:

>>> b_aligned, A_aligned = b.align(A, level=0)
>>> A_aligned.compare(A)
Empty DataFrame
Columns: []
Index: []
>>> b_aligned
                              0         1         2
2021-08-14 11:14:00 0  0.113316  0.208389  0.197855
                    1  0.113316  0.208389  0.197855
                    2  0.113316  0.208389  0.197855
2021-08-14 11:15:00 0  0.476066  0.610945  0.750575
                    1  0.476066  0.610945  0.750575
                    2  0.476066  0.610945  0.750575
2021-08-14 11:16:00 0  0.009947  0.647356  0.735746
                    1  0.009947  0.647356  0.735746
                    2  0.009947  0.647356  0.735746
2021-08-14 11:17:00 0  0.885953  0.768626  0.866064
                    1  0.885953  0.768626  0.866064
                    2  0.885953  0.768626  0.866064
2021-08-14 11:18:00 0  0.439066  0.568404  0.227528
                    1  0.439066  0.568404  0.227528
                    2  0.439066  0.568404  0.227528
>>> A_aligned.mul(b_aligned)
                              0         1         2
2021-08-14 11:14:00 0  0.035078  0.059694  0.015921
                    1  0.112877  0.138816  0.070104
                    2  0.012840  0.043426  0.039147
2021-08-14 11:15:00 0  0.142562  0.397457  0.361405
                    1  0.271504  0.182411  0.508149
                    2  0.226639  0.373254  0.563363
2021-08-14 11:16:00 0  0.008572  0.448457  0.034176
                    1  0.005848  0.252387  0.573175
                    2  0.000099  0.419070  0.541322
2021-08-14 11:17:00 0  0.877118  0.142770  0.247933
                    1  0.736438  0.364615  0.397589
                    2  0.784913  0.590785  0.750067
2021-08-14 11:18:00 0  0.418120  0.060292  0.108610
                    1  0.162505  0.367235  0.198722
                    2  0.192779  0.323083  0.051769

我只是猜测您实际上在做什么,因为您没有指定轴等,但这会产生与您的代码相同的结果:

>>> A.mul(b.align(A, level=0)[0]).sum(axis='columns').unstack(1)
                            0         1         2
2021-08-14 11:14:00  0.110693  0.321797  0.095413
2021-08-14 11:15:00  0.901424  0.962065  1.163256
2021-08-14 11:16:00  0.491205  0.831409  0.960491
2021-08-14 11:17:00  1.267821  1.498642  2.125765
2021-08-14 11:18:00  0.587022  0.728462  0.567631
于 2021-08-18T10:06:08.770 回答