我需要对我的数据应用递归规则:两个连续数字之间的增量不能超过 0.5。
如果第 n 行的值 (x[n]
) 和第 n+1 行的值 (x[n+1]
) 之间的增量是大于此上限,第 n+1 行中的值应替换为 x[n+1] = x[n] + 0.5
然后应该使用 x[n+1]
的新值来查看后续的 x[n+2]
值是否在上限内。
我知道我可以循环执行此操作,但我正在寻找一种矢量化方法来执行此操作。想知道我是否可以使用类似 scipy's lfiltic 的东西,但我还没有看到类似的例子。
示例数据:
pd.Series(np.random.randn(10,))
0 0.016366
1 -1.180037
2 0.967760
3 0.337723
4 -0.230030
5 -0.276347
6 -1.872155
7 -1.242532
8 2.315929
9 -1.723003
示例输出:
0 0.016366
1 -1.180037
2 -0.180037 # <- new value because of cap
3 0.337723
4 -0.230030
5 -0.276347
6 -1.872155
7 -1.242532
8 -0.242532 # <- new value because of cap
9 -1.723003
最佳答案
这是一个只需要 O(log(N))
的解决方案parallel 以需要 O(N*log(N))
为代价传递数据总操作(其中并行传递可能涉及将大范围的连续元素聚合为单个值)。
这是否算作矢量化解决方案取决于您有哪些可用的原语以及您想要将分而治之算法重新表述为矢量化算法的工作量,这是(至少在这种情况下)可能的,但往往需要大量工作。
在基本情况下,您有一个单元素向量,您就完成了。
否则将您的数据分成两半,并递归地将规则应用于每一半。我们称生成的向量为a
和 b
.
让c = [a[-1] + 0.5,a[-1] + 1.0,..]
(其中 a[-1]
是 a
中的最后一个元素)
找到b
中的第一个元素这是 < c
中的相应元素.
i = indexFirstTrue(b < c)
#(返回 len(b)
如果它们都更大)。
然后拼接c
的合适部分:
return a + c[:i] + b[i:]
这里是作为列表上的 Python 函数(这当然违背了整个目的,但它给出了正确的想法):
import itertools
def restrict(x):
l = len(x)
if l == 1:
return x
a = restrict(x[:l//2])
b = restrict(x[l//2:])
c = list(itertools.islice(itertools.count(a[-1]+0.5, 0.5), len(b)))
try:
i = [x < y for (x, y) in zip(b, c)].index(True)
except ValueError:
i = len(b)
return a + c[:i] + b[i:]
关于python - 矢量化 : Limit the increase in value between two subsequent numbers in Series (or list/array/whatever),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46932619/