【问题标题】:Optimise filtering function for runtime in pandas优化 pandas 运行时的过滤功能
【发布时间】:2018-11-21 23:06:08
【问题描述】:
def filter_data(df, raw_col,threshold,filt_col):
    df['pct'] = None
    df[filt_col] = None
    df[filt_col][0] = df[raw_col][0]
    max_val = df[raw_col][0]
    for i in range(1,len(df)):
        df['pct'][i] = (df[raw_col][i] - max_val)*1.0 / max_val
        if abs(df['pct'][i]) < threshold:
            df[filt_col][i] = None
        else:
            df[filt_col][i] = df[raw_col][i]
            max_val = df[raw_col][i]
    df = df.dropna(axis=0, how='any').reset_index()
    return df


from random import randint
some_lst = [randint(50, 100) for i in range(0,50)]
some_df = pd.DataFrame({'raw_col':some_lst})
some_df_filt = filter_data(some_df,'raw_col',0.01,'raw_col_filt')

创建一个新列(filt_col)的目标,其中使用以下逻辑删除数字列(raw_col)中的记录;如果两个相邻行之间的变化率小于阈值,则删除后者。 它可以工作,但在运行时间方面效率很低。 关于如何优化它的任何提示?

【问题讨论】:

  • 您能否分享一个您的初始 df 示例以及您正在寻找的结果?
  • " some_df_filt " 尤其是列 " raw_col_filt " 是理想的输出...
  • 我的意思是mcve。如果你能做到,那么帮助你会更容易。

标签: python pandas filter


【解决方案1】:

IIUC,您可以使用.pct_change()loc 非常简单地做到这一点

第一

df['pctn'] = df.raw_col.pct_change()

然后

threshold  = 0.01
df.loc[df.pctn.abs() >= threshold]

您可以检查此解决方案是否产生与您所说的相同的结果,有效,但速度很慢

df.loc[df.pctn.abs() >= 0.01].raw_col.tolist() == some_df_filt.raw_col.tolist()
True

【讨论】:

  • 这应该是公认的答案。在测试时,加速是几个数量级。如果问题中的算法使用 pandas/numpy api 之外的大量代码(从效率的角度有效地使 pandas/numpy 无用)在数据帧上运行,则此答案有效地使用了 api,将事情排除在 python 领域之外。从实际的角度来看,您不需要比这更好的东西。在我糟糕的桌面用原始算法计算 1000 个数字时,我现在可以在 1.1 秒内用这个答案计算 10,000,000 个。
  • 我试图避免使用这种方法,我想出了我的功能,因为我希望能够毫不费力地在不同语言之间传输逻辑。但仔细想一想,用一个通用的平庸解决方案而不是利用每种语言的长处并没有多大意义。
猜你喜欢
  • 1970-01-01
  • 2019-01-07
  • 2019-01-06
  • 1970-01-01
  • 1970-01-01
  • 2021-07-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多