0

我查看了类似的答案,但找不到适合我的问题的答案。

我有一个构建为 MultiIndex 的每日协方差矩阵。它有“k”个日期,对于每个“k”个日期,它都有一个大小为“n”乘“n”的矩阵。尺寸在技术上是 (k, n, n),但由于这是一个 MultiIndex pandas 将其视为形状 (kxn, n)。

作为一个最低限度的工作示例,我可以提供以下内容:

dates = pd.date_range(start='20120101', end='20210101', freq='D')
X = pd.DataFrame( {'A' : np.random.rand(len(dates)), 'B' : np.random.rand(len(dates)), 'C' : np.random.rand(len(dates)), 'D' : np.random.rand(len(dates)), 'E' : np.random.rand(len(dates)) }, index=dates).ewm(halflife=30, min_periods=1).cov()

我想从每天到每分钟重新采样一次。假设我的 MultiIndex 协方差矩阵被称为“X”,我已经设法让以下工作:

X.unstack().resample("T").first().ffill().stack()

然而,这需要非常长的时间来计算。有没有更快更有效的方法来执行这个操作?

这对于在 pandas 0.24 之后被弃用的面板来说很快。从我自己的分析工作来看,最占用内存的部分似乎是“stack()”

4

1 回答 1

1

IIUC

使用重采样来添加信息('D' -> 'T')不是正确的选择,尤其是如果您想填充前向值。您可以使用np.vsplit创建一个类似面板的然后根据您的 DatetimeIndex 重复您的数组,最后重塑数据:

# Create new MultiIndex
dates2 = pd.date_range(X.index.levels[0].min(),
                       X.index.levels[0].max() + pd.DateOffset(days=1), 
                       freq='T', closed='left')
mi = pd.MultiIndex.from_product([dates2, X.index.levels[1]])

# Manipulate your array
vals = np.array(np.repeat(np.vsplit(X.values, len(X.index.levels[0])), 24*60, axis=0))
vals = vals.reshape(vals.shape[0]*vals.shape[1], vals.shape[2])

# New dataframe
out = pd.DataFrame(vals, index=mi, columns=X.columns)

对于较小的样本:

>>> df
               A   B
2012-01-01 A  11  12
           B  13  14
2012-01-02 A  21  22
           B  23  24
2012-01-03 A  31  32
           B  33  34

# Resample: 12H and 2 values per day
# dates2 = pd.date_range(df.index.levels[0].min(), df.index.levels[0].max() + pd.DateOffset(days=1), freq='12H', closed='left')
# mi = pd.MultiIndex.from_product([dates2, df.index.levels[1]])
# vals = np.array(np.repeat(np.vsplit(df.values, len(df.index.levels[0])), 2, axis=0))
# vals = vals.reshape(vals.shape[0]*vals.shape[1], vals.shape[2])
# out = pd.DataFrame(vals, index=mi, columns=df.columns)

>>> out
                        A   B
2012-01-01 00:00:00 A  11  12
                    B  13  14
2012-01-01 12:00:00 A  11  12
                    B  13  14
2012-01-02 00:00:00 A  21  22
                    B  23  24
2012-01-02 12:00:00 A  21  22
                    B  23  24
2012-01-03 00:00:00 A  31  32
                    B  33  34
2012-01-03 12:00:00 A  31  32
                    B  33  34

使用您的代码:

>>> df.unstack().resample("12H").first().ffill().stack()
                          A     B
2012-01-01 00:00:00 A  11.0  12.0
                    B  13.0  14.0
2012-01-01 12:00:00 A  11.0  12.0
                    B  13.0  14.0
2012-01-02 00:00:00 A  21.0  22.0
                    B  23.0  24.0
2012-01-02 12:00:00 A  21.0  22.0
                    B  23.0  24.0
2012-01-03 00:00:00 A  31.0  32.0
                    B  33.0  34.0
                                   # <- Lost 2012-01-03 12:00:00

X 上的性能

>>> %timeit op_resample()
9.1 s ± 568 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

>>> %timeit new_array()
1.86 s ± 23 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
于 2021-09-08T10:08:16.330 回答