计算 pandas 数据帧中每单位时间的出现率
Computing rate of occurrences per unit of time in a pandas dataframe
我正在寻求计算数据帧中事件发生的速率。
我在 pandas 中有一个数据框,用于跟踪特定事件的发生和持续时间。所以最初它看起来像这样:
onset duration label channels end_time
0 1.5 0.1 HFO A1 10
1 2.0 1.0 HFO A2 10
2 3.0 1.0 HFO A3 10
3 5.5 0.1 HFO A1 10
其中 onset
和 duration
以及 end_time
以秒为单位。 channels
表示我要循环的一组独特的组。
期望的输出
我想得到这样的东西:
rate_dict = {
'A1': 0.2, # rate of 0.2 per second (i.e. 2 occurrences over 10 second time frame)
'A2': 0.1, # rate of 0.1 per second
'A3': 0.1
}
我目前的尝试
首先,我根据 channels
:
得到一个组
for idx, group in df.groupby(['channels']):
然后我将其转换为日期时间索引
onset duration label channels end_time
timestamp
2021-02-10 19:25:19.391130+00:00 1.5 0.1 HFO A1 10
2021-02-10 19:25:23.391130+00:00 5.5 0.1 HFO A1 10
接下来,我考虑重新索引开始时间(0 秒)和结束时间(在本例中为 10 秒):
# rate is say 's' for creating a dummy row for every second
dt_idx = pd.date_range(ref_timestamp, end_timestamp, freq=rate)
group = group.reindex(dt_idx, fill_value=np.nan)
问题是它没有拾取频道 A1 在 1.5 和 5.5 秒处发生的事件。所以我最终基本上得到了所有 nans 的行,而理想情况下我在我重新采样的这段时间里得到了 2 的计数。
期望的泛化
理想情况下,我可以指定其他费率字符串(例如 'hr'),它将 return 每小时费率。在这种情况下,它将是:
rate_dict = {
'A1': 2.0, # rate of 2 per hr (i.e. 2 occurrences over a 1 hour time frame)
'A2': 1.0, # rate of 1 per hr
'A3': 1.0
}
Groupby channels,统计发生次数,除以结束时间。因为每组的出现次数比组大小要少,所以在这种情况下将出现次数定位到 end_time 没有什么坏处,因为没有太大的变化。
df.groupby('channels')['end_time'].agg(lambda x: x.count()/x.mean()).to_dict()
首先,我们可以将您的 table 重新创建为 Pandas DataFrame:
import pandas as pd
d = {'onset': [1.5 ,2.0 ,3.0 ,5.5],
'duration': [0.1, 1.0, 1.0, 0.1],
'label': ['HFO', 'HFO', 'HFO', 'HFO'],
'channels': ['A1', 'A2', 'A3', 'A1'],
'end_time': [10.0, 10.0, 10.0, 10.0]}
df = pd.DataFrame(d)
为了直接解决你的问题,就每秒出现次数而言,我们可以计算出现次数并除以平均值end_time
:
df.groupby('channels').end_time.agg(lambda x: x.count()/x.mean()).to_dict()
为了概括这一点,让我们创建一个函数 to_freq
,它将序列 x
和所需的速率作为字符串 rate
:
作为输入
def to_freq(x, rate='s'):
d = {'s':1, 'm': 60, 'h': 60*60, 'd': 60*60*24}
f = x.count()/x.mean()
return f/d[rate]
现在,我们原来的代码变成了:
df.groupby('channels').end_time.agg(lambda x: to_freq(x)).to_dict()
我们可以找到每小时发生的次数如下:
df.groupby('channels').end_time.agg(lambda x: to_freq(x, rate='h')).to_dict()
我正在寻求计算数据帧中事件发生的速率。
我在 pandas 中有一个数据框,用于跟踪特定事件的发生和持续时间。所以最初它看起来像这样:
onset duration label channels end_time
0 1.5 0.1 HFO A1 10
1 2.0 1.0 HFO A2 10
2 3.0 1.0 HFO A3 10
3 5.5 0.1 HFO A1 10
其中 onset
和 duration
以及 end_time
以秒为单位。 channels
表示我要循环的一组独特的组。
期望的输出
我想得到这样的东西:
rate_dict = {
'A1': 0.2, # rate of 0.2 per second (i.e. 2 occurrences over 10 second time frame)
'A2': 0.1, # rate of 0.1 per second
'A3': 0.1
}
我目前的尝试
首先,我根据 channels
:
for idx, group in df.groupby(['channels']):
然后我将其转换为日期时间索引
onset duration label channels end_time
timestamp
2021-02-10 19:25:19.391130+00:00 1.5 0.1 HFO A1 10
2021-02-10 19:25:23.391130+00:00 5.5 0.1 HFO A1 10
接下来,我考虑重新索引开始时间(0 秒)和结束时间(在本例中为 10 秒):
# rate is say 's' for creating a dummy row for every second
dt_idx = pd.date_range(ref_timestamp, end_timestamp, freq=rate)
group = group.reindex(dt_idx, fill_value=np.nan)
问题是它没有拾取频道 A1 在 1.5 和 5.5 秒处发生的事件。所以我最终基本上得到了所有 nans 的行,而理想情况下我在我重新采样的这段时间里得到了 2 的计数。
期望的泛化
理想情况下,我可以指定其他费率字符串(例如 'hr'),它将 return 每小时费率。在这种情况下,它将是:
rate_dict = {
'A1': 2.0, # rate of 2 per hr (i.e. 2 occurrences over a 1 hour time frame)
'A2': 1.0, # rate of 1 per hr
'A3': 1.0
}
Groupby channels,统计发生次数,除以结束时间。因为每组的出现次数比组大小要少,所以在这种情况下将出现次数定位到 end_time 没有什么坏处,因为没有太大的变化。
df.groupby('channels')['end_time'].agg(lambda x: x.count()/x.mean()).to_dict()
首先,我们可以将您的 table 重新创建为 Pandas DataFrame:
import pandas as pd
d = {'onset': [1.5 ,2.0 ,3.0 ,5.5],
'duration': [0.1, 1.0, 1.0, 0.1],
'label': ['HFO', 'HFO', 'HFO', 'HFO'],
'channels': ['A1', 'A2', 'A3', 'A1'],
'end_time': [10.0, 10.0, 10.0, 10.0]}
df = pd.DataFrame(d)
为了直接解决你的问题,就每秒出现次数而言,我们可以计算出现次数并除以平均值end_time
:
df.groupby('channels').end_time.agg(lambda x: x.count()/x.mean()).to_dict()
为了概括这一点,让我们创建一个函数 to_freq
,它将序列 x
和所需的速率作为字符串 rate
:
def to_freq(x, rate='s'):
d = {'s':1, 'm': 60, 'h': 60*60, 'd': 60*60*24}
f = x.count()/x.mean()
return f/d[rate]
现在,我们原来的代码变成了:
df.groupby('channels').end_time.agg(lambda x: to_freq(x)).to_dict()
我们可以找到每小时发生的次数如下:
df.groupby('channels').end_time.agg(lambda x: to_freq(x, rate='h')).to_dict()