假设我有一些包含某些事件的数据,我想测量事件之间的时间。但有时我有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个索引,第二组之间的间隔是nans,因此被忽略,第三组和第四组之间的间隔是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]
这确实给了我想要的答案。但这感觉就像一个可怕的黑客。有一个更好的方法吗?也许在熊猫里有什么东西?
答案 0 :(得分: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
的区间。
-1
上的searchsorted
说明了np.diff
的转变;作为次要警告,如果在第一个nan
之前有1
s,则此代码无法正常运行(尽管这很容易解决)。
答案 1 :(得分:0)
您可以使用np.ufunc.reduceat
找出哪些片段包含nan,并将其掩盖:
O(n)
这将线性执行,即def sumList(l):
if l == []:
return 0
else:
return l[1:] + [l[0]]
。