List 如何从两个列表中删除对应于单独列表的重复值的非最大值索引?

List 如何从两个列表中删除对应于单独列表的重复值的非最大值索引?,list,python-3.x,numpy,dictionary,duplicates,List,Python 3.x,Numpy,Dictionary,Duplicates,我有两个列表,第一个代表观察时间,第二个代表在这些时间的观察值。我试图找到最大的观测值和相应的时间给定一个不同长度的滚动窗口。例如,下面是两个列表 # 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,

我有两个列表,第一个代表观察时间,第二个代表在这些时间的观察值。我试图找到最大的观测值和相应的时间给定一个不同长度的滚动窗口。例如,下面是两个列表

# 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
缺失时间(ex:3.0)对应于零的观察值,而重复时间对应于地板时间的多个观察值。由于我的窗口将在
时间计数上滚动(例如:前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
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
检查重复项的索引时,此代码似乎只返回重复值第一次出现时的索引。出于代码效率/速度方面的原因,我还尝试通过模块
collections
使用
orderedict
,但字典也有类似的问题。对于非重复观察值,给定重复键,保留重复键的第一个实例和相应的观察值,同时从dict中删除所有其他实例。根据,我的第二次尝试就在下面

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
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]
时间计数=8.0
[4,5,6]
时间计数=10.0
。从重复时间计数中,
475.2
是对应于重复时间计数8.0
max linspeed
400.9
是对应于重复时间计数10.0的
max linspeed
,这意味着在重复时间计数的剩余索引处的其他linspeed将被删除


我不确定我还能尝试什么。我如何调整此方法(或找到一种新方法)以高效地找到与重复值对应的所有索引?如有任何建议,将不胜感激。(PS-我将numpy作为一个标记,因为我认为有一种方法可以通过numpy实现,但我还没有找到。)

好的,如果您想使用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
向量的长度相同,并且包含所需的输出。

不必详细介绍如何实现高效滚动窗口最大过滤器;减少重复值可视为一个分组问题,该软件包(免责声明:我是其作者)为以下方面提供了高效、简单的解决方案:

import numpy_indexed as npi
unique_time, unique_speed = npi.group_by(time_count).max(linspeed)

对于大型输入数据集(即重要的地方),这应该比任何非矢量化解决方案快得多。内存消耗是线性的,性能一般为NlogN;但由于时间计数似乎已经排序,性能也应该是线性的。

我在这里玩的是
np.argmax
。。。我将有机会在大约2小时内测试/玩这个,谢谢。这个解决方案在时间和内存上都是二次的;考虑到所描述的时间序列可能会变得非常大,这可能不是最佳解决方案。没错,尽管可以使用稀疏数组对其进行优化。取决于数据集,什么是值得的?如果时间序列很长,的
循环也会很慢。我还没有熟悉groupby,尽管我看到的示例表明它是多么有用。发布的解决方案适用于我的大型数据集,但我总是喜欢学习其他方法和技巧;谢谢我找到了和,但如果有使用各种函数的示例文档(类似于numpy/scipy文档),这将非常有帮助。是否有任何相关文档我还没有找到?我询问是因为我想知道原始数组的索引(在本例中为
linspeed
),在查找每个副本的最大值时使用或忽略这些索引,以便在其他数组中使用相同的索引。group_by还具有argmax属性。但事实上,你是对的,好的文件会很有帮助,但我还没来得及去做。不过,我很乐意回顾一下公关:)。此外,代码非常干净,所有功能级别的docstring都非常全面,因此在IDE中搜索repo或do go to definition应该可以很好地工作。我还没有学会如何执行PRs,但我计划在未来3-4个月内完成,并且可以让您知道我何时执行。顺便说一句,你关于
argmax
作为属性的提示很有用。