TL; DR:我的问题是我该如何改善我的功能以胜过熊猫自己的最大移动功能?
背景信息:
因此,我正在处理许多移动平均值,最大移动量和最小移动量等,到目前为止,我发现的唯一移动窗口(例如要素)位于pandas.rolling method中。问题是:我拥有的数据是numpy数组,而我想要的最终结果也必须在numpy数组中;我想将其简单地转换为pandas系列并返回numpy array来完成以下工作:
result2_max = pd.Series(data_array).rolling(window).max().to_numpy()
,这太不合常规了,因为转换数据类型似乎是不必要的,并且可能存在纯粹在numpy实现中做完全相同的事情的方法。
但是,尽管看起来很不可思议,但它比我在网上提出或看到的任何方法都快。我将在下面给出一些小基准:
import numpy as np
import pandas as pd
def numpy_rolling_max(data, window):
data = data[::-1]
data_strides = data.strides[0]
movin_window = np.lib.stride_tricks.as_strided(data,
shape=(data.shape[0] - window +1, window),
strides = (data_strides ,data_strides)
)[::-1]
max_window =np.amax(movin_window, axis = 1)#this line seems to be the bottleneck
nan_array = np.full(window - 1, np.nan)
return np.hstack((nan_array, max_window))
def pandas_rolling_max(data, window):
return pd.Series(data).rolling(window).max().to_numpy()
length = 120000
window = 190
data = np.arange(length) + 0.5
result1_max = numpy_rolling_max(data, window)#21.9ms per loop
result2_max = pandas_rolling_max(data, window)#5.43ms per loop
result_comparision = np.allclose(result1_max, result2_max, equal_nan = True)
在arraysize = 120k,window = 190的情况下,大熊猫滚动最大值比numpy版本快约3倍。我不知道从哪里开始,因为我已经尽可能地向量化了自己的函数,但是它仍然比熊猫版本慢很多,我也不知道为什么。
提前谢谢
编辑:我已经找到了瓶颈,它就是这一行:
max_window =np.amax(movin_window, axis = 1)
但是看到它已经是向量化函数调用,我仍然不知道如何进行。
答案 0 :(得分:3)
我们可以使用1D
max filter from Scipy来复制与
// serverMessage: string; No need anymore
serverMessage$: Observable<string>;
constructor(
private cs: CommonService
) {
this.serverMessage$ = this.cs.serverMessage$
.pipe(scan((accumaltor, message) => accumator + message))
// .subscribe((message: string) => {
// this.serverMessage += message;
// });
// No need to subscribe anymore as we will be using the `async pipe`, but if you need `serverMessage` for something else
// You can remove the comments and make it `=` not `+=` as the messages are already concatinated
}
相同的行为,并且仍然会更加有效-
<!-- notice the async pipe here, remove the need to unsubscribe() at ngDestroy() -->
<div class="col-md-12" *ngIf="serverMessage$ | async as serverMessage">
<textarea style="width: 100%" cols="50" rows="10">{{ serverMessage }}</textarea>
</div>
样品运行-
pandas
关于实际测试用例大小的计时-
from scipy.ndimage.filters import maximum_filter1d
def max_filter1d_same(a, W, fillna=np.nan):
out_dtype = np.full(0,fillna).dtype
hW = (W-1)//2 # Half window size
out = maximum_filter1d(a,size=W, origin=hW)
if out.dtype is out_dtype:
out[:W-1] = fillna
else:
out = np.concatenate((np.full(W-1,fillna), out[W-1:]))
return out