我有两个列表,第一个表示观察时间,第二个表示这些时间的观察值。我试图找到最大观测值和给定一个不同长度的滚动窗口的相应时间。例如,这是两个列表。
# observed values
linspeed = [280.0, 275.0, 300.0, 475.2, 360.1, 400.9, 215.3, 323.8, 289.7]
# times that correspond to observed values
time_count = [4.0, 6.0, 8.0, 8.0, 10.0, 10.0, 10.0, 14.0, 16.0]
# actual dataset is of size ~ 11,000
缺失时间(例如:3.0)对应于观察到的零值,而重复时间对应于对覆盖时间的多次观察。由于我的窗口将在time_count
上滚动(例如:前2小时的最大值,接下来的2小时,之后2小时;前4小时的最大值,接下来的4小时......),我计划使用数组重塑例程。但是,在之前正确设置所有内容非常重要,这需要在重复次数时找到最大值。为了解决这个问题,我尝试了下面的代码。
def list_duplicates(data_list):
seen = set()
seen_add = seen.add
seen_twice = set(x for x in data_list if x in seen or seen_add(x))
return list(seen_twice)
# check for duplicate values
dups = list_duplicates(time_count)
print(dups)
>> [8.0, 10.0]
# get index of duplicates
for dup in dups:
print(time_count.index(dup))
>> 2
>> 4
检查重复项的索引时,似乎此代码仅返回重复值第一次出现的索引。我还尝试通过模块OrderedDict
使用collections
出于代码效率/速度的原因,但字典也有类似的问题。给定非重复观察值的重复键,保留重复键的第一个实例和相应的观察值,同时从dict中删除所有其他实例。根据{{3}},我的第二次尝试就在下面。
for dup in dups:
indexes = [i for i,x in enumerate(time_count) if x == dup]
print(indexes)
>> [4, 5, 6] # indices correspond to duplicate time 10s but not duplicate time 8s
对于[2,3]
我应该time in time_count = 8.0
而[4,5,6]
应该time in time_count = 10.0
。从重复的time_counts中,475.2
是max linspeed
,对应于重复的time_count 8.0
,而400.9
是max linspeed
,对应于重复的time_count 10.0
,意思是将删除剩余索引中重复time_counts的其他linspeeds。
我不确定我还能尝试什么。我如何调整(或找到新方法)以有效的方式查找与重复值对应的所有索引?任何意见,将不胜感激。 (PS - 我把numpy变成了一个标签,因为我认为有一种方法可以通过numpy做到这一点,但我还没有想到。)
答案 0 :(得分:1)
好的,如果你想用numpy做这件事,最好是把你的两个列表都变成数组:
l = np.array(linspeed)
tc = np.array(time_count)
现在,找到唯一的时间只是np.unique
来电:
u, i, c = np.unique(tc, return_inverse = True, return_counts = True)
u
Out[]: array([ 4., 6., 8., 10., 14., 16.])
i
Out[]: array([0, 1, 2, 2, 3, 3, 3, 4, 5], dtype=int32)
c
Out[]: array([1, 1, 2, 3, 1, 1])
现在,您可以使用for
循环
m = np.array([np.max(l[i==j]) if c[j] > 1 else l[j] for j in range(u.size)])
m
Out[]: array([ 280. , 275. , 475.2, 400.9, 360.1, 400.9])
或尝试一些2d方法。这可能会更快,但需要进行优化。这只是基本的想法。
np.max(np.where(i[None, :] == np.arange(u.size)[:, None], linspeed, 0),axis = 1)
Out[]: array([ 280. , 275. , 475.2, 400.9, 323.8, 289.7])
现在,您的m
和u
向量长度相同,并包含您想要的输出。
答案 1 :(得分:1)
没有详细介绍如何实现和高效的滚动窗口最大化过滤器;减少重复值可以看作是一个分组问题,numpy_indexed包(免责声明:我是它的作者)提供了有效而简单的解决方案:
import numpy_indexed as npi
unique_time, unique_speed = npi.group_by(time_count).max(linspeed)
对于大型输入数据集(即重要的地方),这应该比任何非矢量化解决方案快得多。内存消耗是线性的,性能一般为NlogN;但由于time_count似乎已经排序,因此性能也应该是线性的。