Pandas 熊猫滚动窗口有效添加新行

Pandas 熊猫滚动窗口有效添加新行,pandas,append,rows,rolling-computation,Pandas,Append,Rows,Rolling Computation,我有一个相当大的数据集(大约500万行),有几个计算列,如lags(1和7)和滚动窗口(7、30、90,每个都有几个值,如mean、std、min、max等等)。现在我需要向df添加一行或多行,我想知道(重新)计算这些特性的最有效方法。重新计算整个df将花费太多时间,但我不能简单地将函数应用于新添加的行 对于滞后,这不是一个大问题,我可以简单地,例如对于滞后1 df.iloc[-1, -2] = df.iloc[-2, -2] 这应该可以解决问题(lag7也是如此),但是滚动窗口呢?同样的方法

我有一个相当大的数据集(大约500万行),有几个计算列,如lags(1和7)和滚动窗口(7、30、90,每个都有几个值,如mean、std、min、max等等)。现在我需要向df添加一行或多行,我想知道(重新)计算这些特性的最有效方法。重新计算整个df将花费太多时间,但我不能简单地将函数应用于新添加的行

对于滞后,这不是一个大问题,我可以简单地,例如对于滞后1

df.iloc[-1, -2] = df.iloc[-2, -2]
这应该可以解决问题(lag7也是如此),但是滚动窗口呢?同样的方法不起作用,我无法在整个数据帧上(重新)运行滚动窗口。我手工计算好吗?还有别的办法吗


Python 3.7.7和pandas 1.0.3

如果我正确地解释了这个问题,那么您有一个大的数据框,其中包含一个或多个源数据列,然后是多个基于源列的带窗口摘要统计信息的列。在向源数据列追加新行后,您试图更新窗口摘要列的底部,而不重新计算整个摘要列

实现这一点的方法取决于许多因素,包括是否使用居中窗口。但希望这能让你开始

我将从你的问题的一个玩具版本开始,有一个
列和两个窗口表示:

[2]中的
:df=pd.DataFrame({'source':np.arange(0,20,2)})
In[3]:对于[3,5]中的窗口:
…:df[f'rolling_mean_{window}']=(
…:df.source.rolling(窗口,中心=True.mean())
...:
然后我们在底部追加一个新行:

[4]中的
:df=df.append(pd.Series({'source':100}),ignore_index=True)
In[5]:df
出[5]:
来源滚动平均值3滚动平均值5
0.0楠楠
1 2.0 2.0 NaN
2      4.0             4.0             4.0
3      6.0             6.0             6.0
4      8.0             8.0             8.0
5     10.0            10.0            10.0
6     12.0            12.0            12.0
7     14.0            14.0            14.0
8 16.0 16.0 NaN
9 18.0楠楠
10100.0楠楠楠
我们必须更新的数据量取决于窗口的长度。例如,为了更新
rolling_mean_3
,我们需要使用最后五行中的信息更新最后两行。为了安全起见,我们可以重新计算最后一个
2*窗口的行数加上您添加的行数:

[6]中的
:df.source.iloc[-(2*window+1):].rolling(window,center=True)。mean()
出[6]:
4楠
5     10.000000
6     12.000000
7     14.000000
8     16.000000
9     44.666667
10南
名称:源,数据类型:float64
这具有第5-10行的正确数据。请注意,第4行在此版本中不正确(现在是
NaN
),但我们可以使用此结果仅更新最后一行
[-(window+1):]
。以下是完整的解决方案:

[7]中的
:更新的\u行=1
In[8]:对于[3,5]中的窗口:
…:update_column_name=f'rolling_mean_{window}'
…:update\u column\u index=df.columns.get\u loc(update\u column\u name)
…:df.iloc[-(窗口+更新的行):,更新的列索引]=(
…:df.source
…:.iloc[-(窗口*2+更新的行):]
…:.rolling(窗口,中心=True).mean()
…:.iloc[-(窗口+更新的行):]
...:     )
In[9]:df
出[9]:
来源滚动平均值3滚动平均值5
0.0楠楠
1 2.0 2.000000南
2      4.0        4.000000             4.0
3      6.0        6.000000             6.0
4      8.0        8.000000             8.0
5     10.0       10.000000            10.0
6     12.0       12.000000            12.0
7     14.0       14.000000            14.0
8     16.0       16.000000            32.0
9 18.0 44.666667 NaN
10100.0楠楠楠
现在,它已经更新为具有正确计算的尾部

从技术上讲,对于居中滚动操作,您只需要更新最后一个
楼层(窗口/2)+更新的_行
行,从数据帧的最后一个
窗口+更新的_行
行绘制。所以你可以这样做来真正优化事情


如果您正在生成不居中的滚动统计数据,方法应该相同,但不包括居中标志。

您只需要估计最后一组项目的平均值。见下文

updated_rows = 1
for window in [3, 5]:
    update_column_name = f'rolling_mean_{window}'
    update_column_index = df.columns.get_loc(update_column_name)
    df.iloc[-(updated_rows):, update_column_index] = df.source.iloc[-(window):].mean()

你能把你试过的东西贴出来吗?为什么不起作用?有关一些最佳实践,请参阅上的这篇文章。做这些事情有很多方法,还有很多方法会出错,所以我们需要知道你从哪里开始。谢谢非常感谢,这正是我想要的。我会尽快试一试,但看起来不错。是的,窗口是居中的,我在最后一列滚动窗口的问题是,它本来会在第一行填充NaN,但您的解决方案非常出色!