如何测量事件开始后经过的时间,并将其记录在新的数据框列中?
How to measure the time elapsed since the beginning of an event, and record it in a new dataframe column?
我正在尝试测量自事件开始以来经过的时间。在这种情况下,我想知道每分钟交易的比特币数量是否超过了某个阈值。因为推动价格的是成交量。所以我想测量有多久的显着体积,并在新列中记录此测量值。
这是一个数据框示例,其中包含索引中的日期、比特币价格和交易量。我添加了一个列,指示音量何时超过某个阈值:
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”列中不能有空值:
>>> 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”事件到最后一个 [=34] 的排名=]-"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)
最后,我们可以使用我们的“排名”列并将其乘以 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
假设 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
我正在尝试测量自事件开始以来经过的时间。在这种情况下,我想知道每分钟交易的比特币数量是否超过了某个阈值。因为推动价格的是成交量。所以我想测量有多久的显着体积,并在新列中记录此测量值。
这是一个数据框示例,其中包含索引中的日期、比特币价格和交易量。我添加了一个列,指示音量何时超过某个阈值:
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”列中不能有空值:
>>> 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”事件到最后一个 [=34] 的排名=]-"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)
最后,我们可以使用我们的“排名”列并将其乘以 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
假设 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