簡體   English   中英

如何使用 Pandas 創建索引循環 FIFO 緩沖區

[英]How to create an indexed circular FIFO buffer with pandas

我正在嘗試創建一個索引循環 FIFO(先進先出)緩沖區,用於保存按分鍾聚合的 Pandas 數據幀中的一組 15 個資產的燭台圖的最后 90 分鍾(即 window_size=150)以實時顯示在客戶端應用程序上(燭台圖)。 它將為每 (1m) 時間步長的每個資產分別保持收盤、開盤、高位、低位和成交量特征。 單個燭台將通過 websocket 更新,其中最新的時間間隔將根據價格(燭台)變化進行更新。 在 Pandas 中表示此數據結構的最有效機制是什么,客戶端應用程序需要輸出形狀 [5,15,90],如 as_frame 所示,表示 [關閉、打開、最高、最低、音量] 15 種資產和 90 間隔分別。

因此,數據將被表示為:

assets  time   close    open    high    low    volume
asset1  time1  0.001    0.002   0.003   0.001  0.001
        time2  0.001    0.001   0.003   0.001  0.001
        ...
        time90 ...

...

asset15 time1  0.001    0.002   0.003   0.001  0.001
        time2  0.001    0.001   0.003   0.001  0.001
        ...
        time90 ...

我已經用 python pandas 實現了一個簡單的解決方案:

class Buffer():
    def __init__(self):
        self.cols = [
                'asset',
                'timestamp',
                'close',
                'high',
                'low'
        ];

        self.lvls = [
            'asset',
            'timestamp'
        ]

        self.frame = pd.DataFrame(
            columns=self.cols
        );

        self.frame.set_index(self.lvls)

    def add(
        self,
        entry
    ):
        ... what would be the most effective
        mechanism to add to the multi indexed
        dataframe given the entry/record 
        {
           "asset":"ASSET",
           "timestamp": 158090000, 
           "close":1.3, 
           "high":1.4, 
           "low":1.2, 
           "open":1.3, 
           "volume":134.5 
        } 
        such that the dataframe timestamp 
        index does not exceed the given 
        window size?

    def as_frame(
        self,
        assets,
        features,
        window_size
    ):
        outframe = self.frame.set_index(self.lvls)
        outframe = outframe.groupby(self.lvls).last()
        outlist = outframe.to_xarray().to_array()
        return outlist

我將如何最有效地在熊貓中實現上述問題? 如果在給定另一種數據結構的情況下不存在更優化/性能更好的解決方案?

添加數據應該像使用帶有dict append一樣簡單,過濾目標DataFrame中的DataFrame

self.frame.append({k:v for k, v in entry.items() if k in self.cols})

基於您的問題,我認為您希望保留一個DataFrame ,它在傳入的數據上保持連續的150秒窗口。

要過濾生成的幀,我會計算最新添加的“開始”時間戳 - 時間窗口,並使用它來過濾行,如下所示:

start_ts = entry['timestamp'] - 150
self.frame = self.frame[ self.frame['ts'] >= start_ts ]

根據DataFrame的大小,您可以獲得更好的性能:

self.frame.drop(self.frame[ self.frame['ts'] < start_ts ].index, inplace=True)

在檢查時間索引的長度后,您可以實現一個轉換:

if len(self.frame.index.levels(1))>=150:
   self.frame = self.frame.shift(1)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM