簡體   English   中英

如何測量事件開始后經過的時間,並將其記錄在新的 dataframe 列中?

[英]How to measure the time elapsed since the beginning of an event, and record it in a new dataframe column?

我正在嘗試測量自事件開始以來經過的時間。 在這種情況下,我想知道每分鍾交易的比特幣數量是否超過了某個閾值。 因為推動價格的是成交量。 因此,我想測量大量交易量持續了多長時間,並將此測量值記錄在一個新列中。

這是一個 dataframe 的示例,其中包含索引中的日期、比特幣價格和交易量。 我添加了一列,指示音量何時超過某個閾值:

df = pd.DataFrame({
    'Time': ['2022-01-11 09:30:00', '2022-01-11 09:31:00', '2022-01-11 09:32:00', '2022-01-11 09:33:00', '2022-01-11 09:34:00', '2022-01-11 09:35:00', ],
    'Volume': ['132', '109', '74', '57', '123', '21'],
    'Volume_cat': ["big_volume", "big_volume", None, None, "big_volume", None],
})

df['Time'] = pd.to_datetime(df['Time'])
df.set_index(['Time'], inplace =True)
df

我的目標是擁有一個新列,顯示自上次檢測到“big_volume”事件以來經過的時間(以秒為單位),並在每次新檢測時重置自身。 這是可以添加到示例代碼中的一行:

df['delta_big_vol'] = ['60', '120', '180', '240', '60', '120',]
df

我必須使用 apply() 方法,但沒有找到任何可行的 lambda。 在偽代碼中它看起來像:

from datetime import timedelta
df['delta_xl_vol'] = df.apply(if df["Volume"] > 100 : return(timedelta.total_seconds))

謝謝你的幫助。

對於這個過程,我們的“Volume_cat”列中不能有 null 個值:

>>> df["Volume_cat"] = df["Volume_cat"].fillna("-")  # This could be any string except "big_volume"

這一步對我們以后有幫助。 我們會記住我們的數據是否以"big_volume"開頭,並且還會存儲第一個“big_volume”行的索引。

>>> idx_of_first_big_volume = df.loc[df["Volume_cat"] == "big_volume"].head(1).index[0]
>>> starts_with_big_volume = idx_of_first_big_volume == df.index[0]

現在,讓我們為“Volume_cat”列中的每組連續值分配一個組(連續的“big_volume”被分組,連續的“-”也被分組)。

>>> df["Group"] = ((df.Volume_cat != df.Volume_cat.shift()).cumsum())

然后,我們將對每個組進行排名。 現在重要的是對連續的組進行分組,從“big_volume”組開始,然后是“-”組,分配從最早的“big_volume”事件到最后一個非新“big_volume”事件的排名(我希望這是有道理的)。 另外,請注意starts_with_big_volume如何幫助我們正確對齊組。 如果我們從“big_volume”組開始,我們需要通過減去 1 來移動值:

>>> df["rank"] = df.groupby((df["Group"] - 1 * starts_with_big_volume)// 2)["Volume_cat"].rank("first", ascending=False)

最后,我們可以使用我們的“rank”列並將其乘以 60 以獲得自最后一行“big_volume”觀察以來的秒數。 由於 output 中的所有這些新列,您可以在 dataframe 的副本中執行此操作,然后在原始 dataframe 中包含“delta_big_vol”列。

>>> df["delta_big_vol"] = 60 * (df["rank"] - 1)

此外,我們現在可以使用我們的idx_of_first_big_volume來滿足您在第一個“big_volume”事件之前用 None 填充所有觀察值的要求:

>>> df.loc[:idx_of_first_big_volume, "delta_big_vol"].iloc[:-1] = None

這應該是您得到的 output:

>>> df
                    Volume  Volume_cat  Group  rank  delta_big_vol
Time                                                              
2022-01-11 09:30:00    132  big_volume      1   1.0            0.0
2022-01-11 09:31:00    109  big_volume      1   2.0           60.0
2022-01-11 09:32:00     74           -      2   3.0          120.0
2022-01-11 09:33:00     57           -      2   4.0          180.0
2022-01-11 09:34:00    123  big_volume      3   1.0            0.0
2022-01-11 09:35:00     21           -      4   2.0           60.0

假設Volume列包含數值數據(你的包含str數據),你可以這樣做

threshold = 100
df['Result'] = (
    df.assign(Result=60).Result
      .groupby((df.Volume > threshold).cumsum()).cumsum()
)

結果

                     Volume  Volume_cat  Result
Time                                           
2022-01-11 09:30:00     132  big_volume      60
2022-01-11 09:31:00     109  big_volume      60
2022-01-11 09:32:00      74        None     120
2022-01-11 09:33:00      57        None     180
2022-01-11 09:34:00     123  big_volume      60
2022-01-11 09:35:00      21        None     120

或者,如果您喜歡從0開始,您可以這樣做

df['Result'] = (
    df.assign(Result=(df.Volume <= threshold) * 60).Result
      .groupby((df.Volume > threshold).cumsum()).cumsum()
)

結果

                     Volume  Volume_cat  Result
Time                                           
2022-01-11 09:30:00     132  big_volume       0
2022-01-11 09:31:00     109  big_volume       0
2022-01-11 09:32:00      74        None      60
2022-01-11 09:33:00      57        None     120
2022-01-11 09:34:00     123  big_volume       0
2022-01-11 09:35:00      21        None      60

編輯評論:我不完全確定,我理解正確。

你可以試試:

threshold = 100
mask = df.Volume > threshold
idx_min = df.index[mask][0]
mask &= ~mask.shift().fillna(False)
df['Result'] = (~mask) * 60
df['Result'] = df.Result.groupby(mask.cumsum()).cumsum().loc[idx_min:]

修改后的樣本框的結果

                     Volume
Time                       
2022-01-11 09:30:00      99
2022-01-11 09:31:00     109
2022-01-11 09:32:00     101
2022-01-11 09:33:00      57
2022-01-11 09:34:00     123
2022-01-11 09:35:00      21

                     Volume  Result
Time                               
2022-01-11 09:30:00      99     NaN
2022-01-11 09:31:00     109     0.0
2022-01-11 09:32:00     101    60.0
2022-01-11 09:33:00      57   120.0
2022-01-11 09:34:00     123     0.0
2022-01-11 09:35:00      21    60.0

暫無
暫無

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

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