[英]Python/Pandas For Loop Time Series
我正在處理面板時間序列數據,並且正在努力創建一個快速的 for 循環,總而言之,當前 i 的過去 50 個數字。 數據就像 600k 行,它開始在 30k 左右攪動。 有沒有辦法在很短的時間內使用 pandas 或 Numpy 來做同樣的事情?
change 列是 float 類型,有 4 位小數。
Index Change
0 0.0410
1 0.0000
2 0.1201
... ...
74327 0.0000
74328 0.0231
74329 0.0109
74330 0.0462
SEQ_LEN = 50
for i in range(SEQ_LEN, len(df)):
df.at[i, 'Change_Sum'] = sum(df['Change'][i-SEQ_LEN:i])
任何幫助將不勝感激! 謝謝!
我用 600k 行嘗試了這個,平均時間是 20.9 ms ± 1.35 ms
這將返回一個包含 df 中最后 50 個更改的滾動總和的系列:
df['Change'].rolling(50).sum()
您可以將其添加到新列中,如下所示:
df['change50'] = df['Change'].rolling(50).sum()
免責聲明:此解決方案無法與.rolling()
競爭。 另外,如果是.groupby()
情況,只需執行df.groupby("group")["Change"].rolling(50).sum()
然后重置索引。 因此,請接受其他答案。
通過將遞歸部分總和轉換為累積總和 ( cumsum
) 的差值,可以避免顯式for
循環。 公式:
Sum[x-50:x] = Sum[:x] - Sum[:x-50] = Cumsum[x] - Cumsum[x-50]
出於展示目的,我將len(df["Change"])
縮短為 10,將SEQ_LEN
為 5。以這種方式幾乎立即完成了 100 萬條記錄。
import pandas as pd
import numpy as np
# data
SEQ_LEN = 5
np.random.seed(111) # reproducibility
df = pd.DataFrame(
data={
"Change": np.random.normal(0, 1, 10) # a million rows
}
)
# step 1. Do cumsum
df["Change_Cumsum"] = df["Change"].cumsum()
# Step 2. calculate diff of cumsum: Sum[x-50:x] = Sum[:x] - Sum[:x-50]
df["Change_Sum"] = np.nan # or zero as you wish
df.loc[SEQ_LEN:, "Change_Sum"] = df["Change_Cumsum"].values[SEQ_LEN:] - df["Change_Cumsum"].values[:(-SEQ_LEN)]
# add idx=SEQ_LEN-1
df.at[SEQ_LEN-1, "Change_Sum"] = df.at[SEQ_LEN-1, "Change_Cumsum"]
df
Out[30]:
Change Change_Cumsum Change_Sum
0 -1.133838 -1.133838 NaN
1 0.384319 -0.749519 NaN
2 1.496554 0.747035 NaN
3 -0.355382 0.391652 NaN
4 -0.787534 -0.395881 -0.395881
5 -0.459439 -0.855320 0.278518
6 -0.059169 -0.914489 -0.164970
7 -0.354174 -1.268662 -2.015697
8 -0.735523 -2.004185 -2.395838
9 -1.183940 -3.188125 -2.792244
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.