python - 为具有最小窗口长度的连续系列过滤 pandas 或 numpy 数组

标签 python performance numpy pandas scipy

我想以仅连续的方式过滤 numpy array(或 pandas DataFrame)保留长度至少为 window_size 的一系列相同值,其他所有值都设置为 0。

例如:

[1,1,1,0,0,1,1,1,1,0,0,1,0,0,0,1,1,1,0,1,1,1,1]

当使用 4 的窗口大小时应该变成

[0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1]

我尝试过使用 rolling_applyscipy.ndimage.filtes.gerneric_filter 但由于滚动内核函数的性质,我认为这不是正确的方法在这里(我现在坚持使用它)。

无论如何,我在这里插入我的尝试:

import numpy as np
import pandas as pd
import scipy
#from scipy import ndimage
df= pd.DataFrame({'x':np.array([1,1,1,0,0,1,1,1,1,0,0,1,0,0,0,1,1,1,0,1,1,1,1])})
df_alt = df.copy()
def filter_df(df, colname, window_size):
    rolling_func = lambda z: z.sum() >= window_size
    df[colname] = pd.rolling_apply(df[colname],
                                    window_size,
                                    rolling_func,
                                    min_periods=window_size/2,
                                    center = True) 

def filter_alt(df, colname, window_size):
    rolling_func = lambda z: z.sum() >= window_size
    return scipy.ndimage.filters.generic_filter(df[colname].values,
                                                rolling_func,
                                                size = window_size,                                       
                                                origin = 0)

window_size = 4
filter_df(df, 'x', window_size)
print df
filter_alt(df_alt, 'x', window_size)

最佳答案

这基本上是一个 image closing operation in image-processing但是对于一维案例。这样的操作可以用卷积方法来实现。现在,NumPy does support 1D convolution ,所以我们很幸运!因此,要解决我们的问题,它会是这样的 -

def conv_app(A, WSZ):
    K = np.ones(WSZ,dtype=int)
    L = WSZ-1
    return (np.convolve(np.convolve(A,K)>=WSZ,K)[L:-L]>0).astype(int)

sample 运行-

In [581]: A
Out[581]: array([1, 1, 1, 0, 0, 1, 1, 1, 1, 0, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1])

In [582]: conv_app(A,4)
Out[582]: array([0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1])

In [583]: A = np.append(1,A) # Append 1 and see what happens!

In [584]: A
Out[584]: array([1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 0, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1])

In [585]: conv_app(A,4)
Out[585]: array([1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1])

运行时测试 -

本节对列出的解决已发布问题的其他几种方法进行了基准测试。它们的定义如下 -

def groupby_app(A,WSZ): # @lambo477's solution
    groups = itertools.groupby(A)
    result = []
    for group in groups:
        group_items = [item for item in group[1]]
        group_length = len(group_items)
        if group_length >= WSZ:
            result.extend([item for item in group_items])
        else:
            result.extend([0]*group_length)
    return result

def stride_tricks_app(arr, window): # @ajcr's solution
    x = pd.rolling_min(arr, window)
    x[:window-1] = 0
    y = np.lib.stride_tricks.as_strided(x, (len(x)-window+1, window), (8, 8))
    y[y[:, -1] == 1] = 1
    return x.astype(int)            

时间 -

In [541]: A = np.random.randint(0,2,(100000))

In [542]: WSZ = 4

In [543]: %timeit groupby_app(A,WSZ)
10 loops, best of 3: 74.5 ms per loop

In [544]: %timeit stride_tricks_app(A,WSZ)
100 loops, best of 3: 3.35 ms per loop

In [545]: %timeit conv_app(A,WSZ)
100 loops, best of 3: 2.82 ms per loop

关于python - 为具有最小窗口长度的连续系列过滤 pandas 或 numpy 数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34616439/

相关文章:

javascript - 使用attr()方法,将属性作为键值对象或直接传递时,哪种方法在jQuery中添加属性时执行最快?

performance - Xamarin 跨平台用户体验与原生开发

c++ - CPP : Parsing String Stream is too slow

python - 解释 Numpy-Array 中的特定位

python - 如何将 numpy.int32 转换为 decimal.Decimal

python - Pandas ,适用于作为数据框行条目的参数

python - 让函数在数据帧的每一行上工作(pandas)

numpy - 使用来自 matplotlib 的 plt.plot() 将所有 numpy 数组绘图点相互连接

python - 是否有一个 Python 库可以简化 CLI 实用程序(如 Django 管理命令)的创建?

python - sys.settrace 仅在函数调用时被调用,而不是每一行