Python 3.x 如何获得数组A中与数组B中唯一值对应的所有最大值的索引?

Python 3.x 如何获得数组A中与数组B中唯一值对应的所有最大值的索引?,python-3.x,numpy,duplicates,max,unique,Python 3.x,Numpy,Duplicates,Max,Unique,假设有一个观察时间数组ts,每个时间对应于vs中的某个观察值。观察时间被视为经过的小时数(从零开始),可以包含重复的时间。我想找出对应于每个唯一观测时间的最大观测值的指数我要求的是索引,而不是几个月前我要求的值。这样,我可以在不同的数组上应用相同的索引。下面是一个示例数据集,我想用它为更大的数据集修改代码 import numpy as np ts = np.array([0, 0, 1, 2, 3, 3, 3, 4, 4, 5, 6, 7, 8, 8, 9, 10]) vs = np.arra

假设有一个观察时间数组
ts
,每个时间对应于
vs
中的某个观察值。观察时间被视为经过的小时数(从零开始),可以包含重复的时间。我想找出对应于每个唯一观测时间的最大观测值的指数我要求的是索引,而不是几个月前我要求的值。这样,我可以在不同的数组上应用相同的索引。下面是一个示例数据集,我想用它为更大的数据集修改代码

import numpy as np
ts = np.array([0, 0, 1, 2, 3, 3, 3, 4, 4, 5, 6, 7, 8, 8, 9, 10])
vs = np.array([500, 600, 550, 700, 500, 500, 450, 800, 900, 700, 600, 850, 850, 900, 900, 900])
我目前的方法是在没有重复时间的任何点拆分值数组

condition = np.where(np.diff(ts) != 0)[0]+1
ts_spl = np.split(ts, condition)
vs_spl = np.split(vs, condition)

print(ts_spl)
>> [array([0, 0]), array([1]), array([2]), array([3, 3, 3]), array([4, 4]), array([5]), array([6]), array([7]), array([8, 8]), array([9]), array([10])]

print(vs_spl)
>> [array([500, 600]), array([550]), array([700]), array([500, 500, 450]), array([800, 900]), array([700]), array([600]), array([850]), array([850, 900]), array([900]), array([900])]
在这种情况下,应计算任何重复时间的重复最大值。在此示例中,返回的索引为:

[1, 2, 3, 4, 5, 8, 9, 10, 11, 13, 14, 15]
# indices = 4,5,6 correspond to values = 500, 500, 450 ==> count indices 4,5
# I might modify this part of the algorithm to return either 4 or 5 instead of 4,5 at some future time

虽然我还没有能够根据自己的目的调整此算法,但我认为一定有可能利用
vs\u spl
中以前分割的每个数组的大小来保留索引计数器。这种方法是否适用于大型数据集(填充前每个数组10000个元素;填充后每个数组70000个元素)?如果是,我如何调整它?如果没有,还有什么其他方法可能有用呢?

70000并没有那么大,所以是的,它应该是可行的。但是,避免拆分和使用相关UFUNC的
.reduceat
方法更快
reduceat
类似于reduce应用于块,但您不必提供块,只需告诉
reduceat
您将在何处进行剪切即可。比如说这样,

import numpy as np


N = 10**6
ts = np.cumsum(np.random.rand(N) < 0.1)
vs = 50*np.random.randint(10, 20, (N,))

#ts = np.array([0, 0, 1, 2, 3, 3, 3, 4, 4, 5, 6, 7, 8, 8, 9, 10])
#vs = np.array([500, 600, 550, 700, 500, 500, 450, 800, 900, 700, 600, 850, 850, 900, 900, 900])


# flatnonzero is a bit faster than where
condition = np.r_[0, np.flatnonzero(np.diff(ts)) + 1, len(ts)]
sizes = np.diff(condition)
maxima = np.repeat(np.maximum.reduceat(vs, condition[:-1]), sizes)
maxat = maxima == vs
indices = np.flatnonzero(maxat)
# if you want to know how many maxima at each hour
nmax = np.add.reduceat(maxat, condition[:-1])
将numpy导入为np
N=10*6
ts=np.cumsum(np.rand.rand(N)<0.1)
vs=50*np.random.randint(10,20,(N,))
#ts=np.数组([0,0,1,2,3,3,3,4,4,5,6,7,8,8,9,10])
#vs=np.数组([500600550700500450800900700600600850 900900900])
#flatnonzero比where快一点
条件=np.r_u0,np.flatnonzero(np.diff(ts))+1,len(ts)]
尺寸=np.差异(条件)
最大值=np.重复(np.最大值减少(vs,条件[:-1]),大小)
maxat=maxima==vs
指数=np.平坦非零(最大值)
#如果你想知道每小时有多少个最大值
nmax=np.add.reduceat(maxat,条件[:-1])

当前在手机上。我可以在大约一个小时内测试和玩这个。谢谢我想我什么都遵循,除了行
condition=np.r\u0,np.flatnonzero(np.diff(ts))+1,len(ts)]
。据我所知,
np.flatnonzero
按时间顺序返回非零值的索引,您可以对照连续观察时间进行检查。你关于
.reduceat
的提示很有帮助。从文档中,我看到
np.r
可以构建数组,但是您能解释一下它在这行中的用法吗?
flatnonzero
与您代码中的
where
完全相同
r_
应用于向量和标量只是将它们连接起来,因此在本例中,我们在左侧添加一个零,在右侧添加长度。这样,我们不仅有内部边界,还有外部边界。这是很有用的,例如,当一个人想要像我们在下一行中所做的那样计算块的大小时。