【问题标题】:Counting a range of values IF they occur for a certain time interval如果它们在特定时间间隔内出现,则计算一系列值
【发布时间】:2015-12-12 11:42:17
【问题描述】:

我设置了以下 pandas 数据框以从 csv 导入:

df = pd.read_csv('file_path',
                 parse_dates={'timestamp': ['Date','Time']},
                 index_col='timestamp',
                 usecols=['Date', 'Time', 'X'],)

所以它最终有一个日期时间作为索引和一个 int64 对象“X”作为值。

我的数据看起来像这样,有两列:

              X
timestamp   
2015-08-25 16:52:10 95
2015-08-25 16:52:12 84
2015-08-25 16:52:14 86
2015-08-25 16:52:16 84
2015-08-25 16:52:18 85
2015-08-25 16:52:20 86
2015-08-25 16:52:22 84
2015-08-25 16:52:24 95
2015-08-25 16:52:28 95
2015-08-25 16:52:48 80
2015-08-25 16:52:50 85
2015-08-25 16:52:52 85
2015-08-25 16:52:54 84
2015-08-25 16:52:56 85
2015-08-25 16:52:58 86
2015-08-25 16:53:00 85
2015-08-25 16:53:02 85
2015-08-25 16:53:04 85
2015-08-25 16:53:06 86
2015-08-25 16:53:08 85
2015-08-25 16:53:10 85

但是,间隔并不总是一致的。有时我的数据点相隔超过两秒(即 16:52:28-16:52:48)。

我想要的值是 X = [84, 86] 但仅当它们出现至少连续 10 秒时。

所以在我的数据框中,我希望 python 在 16:52:12-22 和 16:52:50-16:53:10 仅返回 2 个计数。

如何告诉 python 不将 16:52:50-16:53:10 计为 2?我可以为特定的时间间隔编写代码,但是如何将“至少 Y 连续秒”翻译成 python?

提前致谢。

编辑:澄清一下,我的首选输出是计数事件 Y 在样本集中发生的次数。当 X 具有至少连续 10 秒的值时,事件 Y 发生。因此,例如,如果 X 至少连续 10 秒处于 84-86,那么我希望它是 1。

【问题讨论】:

  • 您能否提供此示例所需的输出?这样可以更清楚地说明问题。
  • 感谢您的输入,会做的
  • 抱歉,有一点我还不清楚。 “84-86”是什​​么意思。如果我们假设 X 的值至少连续 10 秒保持不变,这很简单。但是您想检查它是否在 10 秒内保持间隔?
  • @RomainX 是的,就是这样。我想检查它是否保持在 84-86 范围内至少连续 10 秒
  • In this case, 10 continuous seconds means 10 consecutive seconds. 这是循环的。你是说至少 10 秒的时间段,采样率是每 2 秒一次,没有中断?

标签: python pandas dataframe


【解决方案1】:

我不确定你到底想做什么,但我给你一个答案至少有助于澄清期望。

# Test data    
df = pd.DataFrame([('2015-08-25 16:52:10', 95),
  ('2015-08-25 16:52:12', 84),
  ('2015-08-25 16:52:14', 86),
  ('2015-08-25 16:52:16', 84),
  ('2015-08-25 16:52:18', 85),
  ('2015-08-25 16:52:20', 86),
  ('2015-08-25 16:52:22', 84),
  ('2015-08-25 16:52:24', 95),
  ('2015-08-25 16:52:28', 95),
  ('2015-08-25 16:52:48', 80),
  ('2015-08-25 16:52:50', 85),
  ('2015-08-25 16:52:52', 85),
  ('2015-08-25 16:52:54', 84),
  ('2015-08-25 16:52:56', 85),
  ('2015-08-25 16:52:58', 86),
  ('2015-08-25 16:53:00', 85),
  ('2015-08-25 16:53:02', 85),
  ('2015-08-25 16:53:04', 85),
  ('2015-08-25 16:53:06', 86),
  ('2015-08-25 16:53:08', 85),
  ('2015-08-25 16:53:10', 85)],
                 columns=['timestamp', 'x'])

df['timestamp'] = pd.to_datetime(df['timestamp'])
df = df.set_index('timestamp')

# Define a period column to indicate the period when the values occur
new = df.groupby(pd.TimeGrouper('10s'),as_index=False).apply(lambda x: x['x'])
df['period'] = new.index.get_level_values(0)
# Group by period and value and count the number of values to see the distinct values and how many time they occur by period
df = df.reset_index()
grouped = df.groupby(['period','x']).count()
print(grouped.head(10))

           timestamp
period x            
0      84          2
       85          1
       86          1
       95          1
1      84          1
       86          1
       95          2
3      80          1
4      84          1
       85          3

【讨论】:

  • 感谢您的回答,我知道这将帮助我评估我所得到的。我添加了原始帖子以希望使我想要的结果更清晰。
【解决方案2】:

举个例子:

>>> df
             timestamp   x
0  2015-08-25 16:52:10  95
1  2015-08-25 16:52:12  84
2  2015-08-25 16:52:14  86
3  2015-08-25 16:52:16  84
4  2015-08-25 16:52:18  85
5  2015-08-25 16:52:20  86
6  2015-08-25 16:52:22  84
7  2015-08-25 16:52:24  95
8  2015-08-25 16:52:28  95
9  2015-08-25 16:52:48  80
10 2015-08-25 16:52:50  85
11 2015-08-25 16:52:52  85
12 2015-08-25 16:52:54  84
13 2015-08-25 16:52:56  85
14 2015-08-25 16:52:58  86
15 2015-08-25 16:53:00  85
16 2015-08-25 16:53:02  85
17 2015-08-25 16:53:04  85
18 2015-08-25 16:53:06  86
19 2015-08-25 16:53:08  85
20 2015-08-25 16:53:10  85

首先,让我们得到一个新列,其中包含两个时间戳之间的间隔:

>>> tl=df['timestamp']
>>> df['interval']=[(tl[i+1]-tl[i]).total_seconds() for i, _ in enumerate(tl[:-1])]+[0]
>>> df
             timestamp   x  interval
0  2015-08-25 16:52:10  95         2
1  2015-08-25 16:52:12  84         2
2  2015-08-25 16:52:14  86         2
3  2015-08-25 16:52:16  84         2
4  2015-08-25 16:52:18  85         2
5  2015-08-25 16:52:20  86         2
6  2015-08-25 16:52:22  84         2
7  2015-08-25 16:52:24  95         4
8  2015-08-25 16:52:28  95        20
9  2015-08-25 16:52:48  80         2
10 2015-08-25 16:52:50  85         2
11 2015-08-25 16:52:52  85         2
12 2015-08-25 16:52:54  84         2
13 2015-08-25 16:52:56  85         2
14 2015-08-25 16:52:58  86         2
15 2015-08-25 16:53:00  85         2
16 2015-08-25 16:53:02  85         2
17 2015-08-25 16:53:04  85         2
18 2015-08-25 16:53:06  86         2
19 2015-08-25 16:53:08  85         2
20 2015-08-25 16:53:10  85         0

现在,使用 Python 的 groupby 来获取每个区间跨度:

fmt='{} sec interval between {} and {} every {} seconds\n\tx={}, count={}\n'
for k, l in groupby(df.iterrows(), key=lambda row: row[1]['interval']):
    li=list(l)
    t2, t1=li[-1][1]['timestamp'], li[0][1]['timestamp']
    ti=(t2-t1).total_seconds()
    if ti>=10.0:
        data=[e[1]['x'] for e in li]
        print fmt.format(ti, t1, t2, k, data, Counter(data))

打印:

12.0 sec interval between 2015-08-25 16:52:10 and 2015-08-25 16:52:22 every 2.0 seconds
    x=[95, 84, 86, 84, 85, 86, 84], count=Counter({84: 3, 86: 2, 85: 1, 95: 1})

20.0 sec interval between 2015-08-25 16:52:48 and 2015-08-25 16:53:08 every 2.0 seconds
    x=[80, 85, 85, 84, 85, 86, 85, 85, 85, 86, 85], count=Counter({85: 7, 86: 2, 80: 1, 84: 1})

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-08-01
    • 1970-01-01
    • 2021-06-26
    • 1970-01-01
    • 1970-01-01
    • 2017-08-25
    • 2018-10-16
    • 1970-01-01
    相关资源
    最近更新 更多