“汽车旅馆”是对信号做出平稳反应的一种方式。你知道吗
例如:给定采用整数值1-5的时变信号St,以及为每个信号分配[-1,0,+1]的响应函数Ft({S0…t}),标准汽车旅馆响应函数将返回:
如果我在信号{S}时有一个数据帧,有没有一种矢量化的方法来应用这个motelling函数?你知道吗
例如,如果数据帧df['S'].values = [1, 2, 2, 2, 3, 5, 3, 4, 1]
那么是否有一种矢量化方法可以产生:
df['F'].values = [-1, -1, -1, -1, 0, 1, 0, 0, -1]
或者,如果没有矢量化的解决方案,是否有比我现在使用的DataFrame.itertuples()
方法更快的方法?你知道吗
df = pd.DataFrame(np.random.random_integers(1,5,100000), columns=['S'])
# First set response for time t
df['F'] = np.where(df['S'] == 5, 1, np.where(df['S'] == 1, -1, 0))
# Now loop to apply motelling
previousF = 0
for row in df.itertuples():
df.at[row.Index, 'F'] = np.where((row.S >= 4) & (previousF == 1), 1,
np.where((row.S <= 2) & (previousF == -1), -1, row.F))
previousF = row.F
对于复杂的数据帧,循环部分需要O(每百万行分钟数)!你知道吗
你可以试试正则表达式。你知道吗
我们正在寻找的模式是
(1)1后跟1或2。(我们选择此规则是因为1之后的任何2都可以被视为1并保持对下一行结果的影响)
(2)5后跟4或5。(同样地,5之后的任何4都可以被视为5)
(1)将产生连续的
-1
s,(2)将产生连续的1
s。其余不匹配的将为0。你知道吗使用这些规则,剩下的工作就是做替换。我们特别使用了一种方法
lambda m: "x"*len(m.group(0))
,它可以将匹配结果转换为此类匹配的长度。(见参考)更大的数据集
参考
Replace substrings in python with the length of each substring
为了汇总其他答案,首先我应该注意到,
DataFrame.itertuples()
显然不是确定性地迭代,或者如预期的那样迭代,因此OP中的样本并不总是在大样本上产生正确的结果。你知道吗多亏了其他答案,我意识到机械地应用motelling逻辑不仅能产生正确的结果,而且当我们使用
DataFrame.fill
函数时,它的速度惊人地快:对于所有定时测试,我们将在相同的输入上操作:
对于上面基于数据帧的函数,我们得到:
这是可以接受的表现。你知道吗
tai was first to present this very clever solution using RegEx(这正是我上述函数的灵感所在),但它无法与停留在数字空间的速度相匹配:
但是没有什么能比编译代码更好。感谢evamicur for this solution using the convenient numba in-line compiler:
你可能会注意到,由于F[t]的连续元素相互依赖,这就不能很好地向量化。在这种情况下我倾向于使用麻木。您的函数很简单,它可以在numpy数组上工作(系列只是引擎盖下的数组),并且不容易矢量化->;numba是实现这一点的理想选择。你知道吗
导入和功能:
在这里,我们可以jit编译函数
并确保normal和jit版本返回预期值
结果:
对于计时,让我们缩放:
结果:
对于你的百万数据点(没有时间正常的功能,因为我不想等待=))
结果:
砰!不到一秒钟就有一百万个条目。这种方法简单、可读性强、速度快。唯一的缺点是对Numba的依赖,但它包含在anaconda中,在conda中很容易获得(也许pip我不确定)。你知道吗
相关问题 更多 >
编程相关推荐