我想知道是否有一些矢量化技巧可以比在一個回圈和大量二進制搜索中實作這一點的簡單解決方案更好地做到這一點:
Dataframe 1 有一個包含任意時間戳(微秒解析度)的時間欄位,它不小,包含幾百萬行。
Dataframe 2 也有一個包含任意時間戳的時間欄位,但這些時間戳通常不會匹配 DF1 中的任何時間戳。DF2 還包含帶有測量值的列。
現在,DF1 應該通過以下方式與 DF2 連接:對于 DF1 中時間戳為 t1 的每一行,找到 DF2 中時間戳在 t1-INTVL 到 t1 間隔內的所有行,例如最后半小時內的所有時間戳。在這些行上聚合測量列,并將 DF1 中的行與這些聚合列連接起來。
是否有任何方法可以幫助做到這一點,而不是簡單地實作我在 Python 代碼中描述的內容?
由于人們對此表示反對,可能是因為我沒有提供“瑣碎”解決方案的代碼,所以這是我當前的瑣碎解決方案(dfg=DF1,dfb=DF2):
# Step 1: for all rows create a dictionary from original timestamp to aggregated variable series
aggcols = [c for c in DF2.columns if c not in ["timestamp"]] # columns which can be summed
def calc_agg(df, ts_to, cols):
ts_from = ts_to - pd.Timedelta(minutes=30)
intvl_rows = df[(df["timestamp"] <= ts_to) & (df["timestamp"] >= ts_from)]
agg = intvl_rows[cols].sum()
return agg
ts2ser = {
ts: calc_agg(DF2, ts, aggcols) for ts in DF1["timestamp"]
}
# Step 2: add the aggregated columns to the original DF1
for c in aggcols:
DF1[c] = DF1["timestamp"].apply(lambda x: ts2ser[x][c])
這可行,但它實際上以逐行方式處理 DF1。
所以問題是:我是否錯過了 pandas/numpy 中可以使其更具可擴展性的任何內容?
uj5u.com熱心網友回復:
您可以嘗試以下方法:
df1 = df1.merge(
pd.concat(
[df2, df1.loc[~df1["timestamp"].isin(df2["timestamp"]), ["timestamp"]]]
)
.fillna(0)
.sort_values("timestamp")
.rolling("30T", on="timestamp").sum(),
on="timestamp", how="left"
)
- 首先將行添加到
df2那些df1尚未在df2.timestamp這些新行之外的值是NaN。如果0會更好,然后.fillna(0)在concat. - 對新的資料框進行排序
timestamp。 .rolling以timestamp30 分鐘的視窗求和。也許您必須將關鍵字引數調整closed為"both"(或自 Pandas 1.4.0 起inclusive="both") - 取決于您到底想要什么。- 現在將結果與
df1on合并timestamps。
我已經針對具有數百萬行的示例資料幀運行了這個,它看起來相當快,比你的版本快得多。它還可以從您的程式中重現結果。
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/510814.html
