如果在列表压缩中的for循环中,则“ generator”对象不可调用

时间:2018-11-12 10:23:44

标签: python pandas performance

运行此程序时出现以下错误:

df['initial_referrer'].apply(lambda x: value.split("utm_campaign=",1)[1] if 'utm_campaign' in value else np.nan for value in x.split('&'))
  

TypeError:“生成器”对象不可调用

我不确定错误的含义以及如何修改此错误以摆脱此错误。我在这里读过几个类似的问题,但无法弄清楚我们可能是什么问题。

所以我在df ['initial_referrer']中有值,如下所示:

df['initial_referrer'].head()
0    /login/index.php
1    /login/index.php?utm_source=INTERNAL&utm_medium=EMAIL&utm_campaign=login-day1
2    /login/index.php
3    /login/index.php?utm_source=INTERNAL&utm_medium=EMAIL&utm_campaign=login-day1
4    /login/index.php

在此,我想提取utm_campaign的值,该值是login-day1,这就是为什么我使用for循环,然后使用if语句来处理2000万行花费很多时间/天的原因。因此,我想使用生成器表达式或列表压缩来更快地对其进行处理。

1 个答案:

答案 0 :(得分:5)

首先将apply常规函数一起使用具有启发性:

def func(x):
    return [value.split("utm_campaign=",1)[1] if 'utm_campaign' in value else np.nan \
            for value in x.split('&')]

df['initial_referrer'].apply(func)

请注意代表列表理解的方括号。您需要将此转换为您的lambda函数:

df['initial_referrer'].apply(lambda x: [value.split("utm_campaign=",1)[1] if 'utm_campaign' in value else np.nan for value in x.split('&')])

但是后者不可读。最好编写一个常规函数。

注意pd.Series.apply是Python级别的循环。您可以改用map,这样可能会改善性能:

df['initial_referrer'] = list(map(func, df['initial_referrer'].values))

甚至是列表理解:

df['initial_referrer'] = [func(x) for x in df['initial_referrer'].values]