【发布时间】:2020-08-20 17:38:38
【问题描述】:
我有一个参差不齐(意思是非常规频率)、时间索引的 DataFrame,我想对其执行时间加权滚动平均,以保持 DataFrame 的原始索引。假定记录的值在被另一个值取代之前是有效的。实现这一点的一种方法是将参差不齐的 DataFrame 上采样到统一频率,然后进行滚动平均:
import pandas as pd
import numpy as np
def time_weighted_average_using_upsampling(df: pd.DataFrame, avg_window: str) -> pd.DataFrame:
# Leads to high memory usage
original_index = df.index.copy()
avg = (
df.resample("1s")
.ffill()
.rolling(avg_window, closed="left", min_periods=int(avg_window[0])))
.mean()
.reindex(original_index)
)
return avg
if __name__ == "__main__":
df = pd.DataFrame(
{"A": [0, 1, 2, 3, 4, 5]},
index=[
pd.Timestamp("20130101 09:00:00"),
pd.Timestamp("20130101 09:00:02"),
pd.Timestamp("20130101 09:00:03"),
pd.Timestamp("20130101 09:00:05"),
pd.Timestamp("20130101 09:00:06"),
pd.Timestamp("20130101 09:00:10"),
],
)
expected_avg = pd.DataFrame(
{"A": [np.nan, np.nan, 1 / 3, 5 / 3, 7 / 3, 4]},
index=[
pd.Timestamp("20130101 09:00:00"),
pd.Timestamp("20130101 09:00:02"),
pd.Timestamp("20130101 09:00:03"),
pd.Timestamp("20130101 09:00:05"),
pd.Timestamp("20130101 09:00:06"),
pd.Timestamp("20130101 09:00:10"),
],
)
pd.testing.assert_frame_equal(
time_weighted_average_using_upsampling(df=df, avg_window="3s"), expected_avg
)
这个问题是上采样破坏了参差不齐的 df 提供的稀疏表示的目的。稀疏表示是内存高效的,而上采样版本则不是。这就引出了一个问题:如何在不必对整个df进行上采样的情况下获得上面显示的结果?
【问题讨论】:
-
这是一个有趣的问题,如果您的问题是不立即对整个数据帧进行上采样,那么也许您可以考虑仅对最后 3 行进行上采样并像
df.rolling(3, closed='left').apply(lambda x: x.resample("1s").ffill()[-4:-1].mean())一样进行计算,但这赢了我猜这不是很有效,因为你在最后执行了许多上采样 -
我也考虑过这种方法。它将处理内存限制,但存在实际挑战,其中一个我不知道如何解决。
df.rolling().apply()除了样本数组之外不提供可调用的任何内容,因此您不能使用 df 操作。 -
也许我误解了你说的数组,但是
df.rolling().apply()确实将一个系列传递给它,而不是现在的一个 numpy 数组。参数raw has been added in v0.23,似乎在这个早期版本中默认设置为True,但由于似乎默认是False,它传递了一个Serie,因此索引可用 -
你完全正确!我的错。我使用的是稍旧版本的 pandas。
标签: python pandas dataframe rolling-computation