我正在嘗試測量自事件開始以來經過的時間。在這種情況下,我想知道每分鐘的位元幣交易量是否超過了某個閾值。因為推動價格的是成交量。因此,我想測量大量交易量持續了多長時間,并將此測量結果記錄在新列中。
這是一個資料框示例,其中包含索引中的日期、位元幣價格和交易量。我添加了一個列,指示音量何時超過某個閾值:
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))
謝謝你的幫助。
uj5u.com熱心網友回復:
對于這個程序,我們的“Volume_cat”列中不能有空值:
>>> df["Volume_cat"] = df["Volume_cat"].fillna("-") # This could be any string except "big_volume"
這一步將在未來幫助我們。我們會記住我們的資料是否以 a 開頭"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”觀察以來的秒數。您可以在資料幀的副本中執行此操作,然后在原始資料幀中包含“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
這應該是您得到的輸出:
>>> 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
uj5u.com熱心網友回復:
假設該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
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/432164.html
上一篇:如何在顫振/飛鏢中創建時隙
