将具有多个返回值的矢量化函数应用于pandas数据框

时间:2020-01-13 18:34:28

标签: python pandas dataframe

我有一个数据框,其中包含一个包含“ Log”字符串的列。 我想根据从“日志”列中解析出的值创建一个新列。 目前,我正在使用具有以下功能的.apply()

def classification(row):
    if 'A' in row['Log']:
        return 'Situation A'
    elif 'B' in row['Log']:
        return 'Situation B'
    elif 'C' in row['Log']:
        return 'Situation C'
    return 'Check'

它看起来像: df['Classification'] = df.apply(classification, axis=1) 问题在于,这需要花费大量时间(对于具有4M行的数据框,大约需要3分钟),我正在寻找一种更快的方法。 我看到了一些用户使用矢量化函数的示例,这些函数的运行速度要快得多,但函数中没有if语句。 我的问题-是否可以向量化我添加的功能,什么是最快的执行方法
这个任务吗?

1 个答案:

答案 0 :(得分:2)

我不确定使用嵌套的numpy.where会提高性能:这里有些测试性能为4M行

import numpy as np
import pandas as pd

ls = ['Abc', 'Bert', 'Colv', 'Dia']
df =  pd.DataFrame({'Log': np.random.choice(ls, 4_000_000)})

df['Log_where'] = np.where(df['Log'].str.contains('A'), 'Situation A', 
                      np.where(df['Log'].str.contains('B'), 'Situation B', 
                          np.where(df['Log'].str.contains('C'), 'Situation C', 'check')))


def classification(x):
    if 'A' in x:
        return 'Situation A'
    elif 'B' in x:
        return 'Situation B'
    elif 'C' in x:
        return 'Situation C'
    return 'Check'


df['Log_apply'] = df['Log'].apply(classification)

嵌套np.where性能

 %timeit np.where(df['Log'].str.contains('A'), 'Situation A', np.where(df['Log'].str.contains('B'), 'Situation B',np.where(df['Log'].str.contains('C'), 'Situation C', 'check')))
8.59 s ± 1.71 s per loop (mean ± std. dev. of 7 runs, 1 loop each)

应用地图性能

%timeit df['Log'].apply(classification)
911 ms ± 146 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

至少在我使用嵌套np.where的计算机上,其速度比applymap慢10倍。

最后的发言:使用评论中建议的解决方案,例如:

d = {'A': 'Situation A',
     'B': 'Situation B',
     'C': 'Situation C'}
df['Log_extract'] = df['Log'].str.extract('(A|B|C)')
df['Log_extract'] = df['Log_extract'].map(d).fillna('Check')

存在以下问题:

  1. 不会必须更快-在我的计算机上进行测试:

    %timeit df['Log_extract'] = df['Log'].str.extract('(A|B|C)')
    3.74 s ± 70.7 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
    
  2. .extract方法遵循字符串顺序,即从字符串'AB'中提取'A',并从'BA'中提取'B'。另一方面,OP函数classification具有提取的层次结构,因此在两种情况下都提取'A'