在numpy/pandas中隐藏nan事件间隔的优雅方式

2024-04-26 00:34:48 发布

您现在位置:Python中文网/ 问答频道 /正文

假设我有一些包含特定事件的数据,我想测量事件之间的时间。但有时我会有nan值,因为没有测量。我不想包括这些时间间隔,因为我真的不知道那里发生了什么。你知道吗

例如,给定:

import numpy as np
a = np.array([0, 1, 0, 0, 0, 1, 0, 0, np.nan, np.nan, 1, 0, 0, 0, 0, 1])

我想回到[4, 5],因为第一组索引之间的间隔是4个索引,第二组索引之间的间隔是nan,因此被忽略,第三组和第四组索引之间的间隔是5个索引。[4, nan, 5]也可以作为输出。你知道吗

我可以做到以下几点:

a_mod = a.copy()
a_mod[np.isnan(a)] = -1e9  # some value I know is larger than my interval will ever be
a_sum = np.cumsum(a_mod)
a_sum_pts = a_sum[a == 1]
mask = np.diff(a_sum_pts) > 0
events = np.where(a == 1)[0]
intervals = np.diff(events)
good_intervals = intervals[mask]

这确实给了我想要的答案。但这感觉像一个可怕的黑客。有更好的方法吗?也许熊猫身上有什么?你知道吗


Tags: 数据importmod间隔np时间事件diff
2条回答

试着简单一点

idx, = np.where(a==1)
nanidx, = np.where(np.isnan(a))

intervals = np.diff(idx)
good_intervals = np.delete(intervals, np.searchsorted(idx, nanidx)-1)

这只是查找1的位置和nan的位置,然后删除包含nan的间隔。你知道吗

searchsorted上的-1说明了np.diff的移位;作为一个小警告,如果在第一个1之前有nan,则此代码不能正常工作(尽管这很容易纠正)。你知道吗

您可以使用^{}找出哪些片段包含nan,并将其屏蔽:

>>> idx, = np.where(a == 1)
>>> mask = np.logical_or.reduceat(np.isnan(a), idx)[:-1]
>>> np.diff(idx)[~mask]
array([4, 5])

这将线性执行,即O(n)。你知道吗

相关问题 更多 >