如何将多个函数应用于单个pandas数据框列?

3
我很想知道是否可以将多个函数应用于单个pandas数据帧列。例如,假设我有三个函数:

In:

def foo(col):
    if 'hi' in col:
        return 'TRUE'

def bar(col):
    if 'bye' in col:
        return 'TRUE'

def baz(col):
    if 'ok' in col:
        return 'TRUE'

以下是数据框:

dfs = pd.DataFrame({'col':['The quick hi brown fox hi jumps over the lazy dog', 
                           'The quick hi brown fox bye jumps over the lazy dog', 
                           'The NO quick brown fox ok jumps bye over the lazy dog']})

如果我想将每个函数应用于 col,通常会使用pandas的apply函数:

dfs['new_col1'] = dfs['col'].apply(foo)

dfs['new_col2'] = dfs['col'].apply(bar)

dfs['new_col3'] = dfs['col'].apply(baz)

dfs

输出:

    col     new_col1    new_col2    new_col3
0   The quick hi brown fox hi jumps over the lazy dog   TRUE    None    None
1   The quick hi brown fox bye jumps over the lazy...   TRUE    TRUE    None
2   The NO quick brown fox ok jumps bye over the l...   None    TRUE    TRUE

然而,正如您所看到的,我创建了3列。 因此,我的问题是如何同时将上述3个函数高效地应用于特定列的大型数据框中? 预期结果应为:
    col                                                 new_col
0   The quick hi brown fox hi jumps over the lazy dog   TRUE
1   The quick hi brown fox bye jumps over the lazy...   TRUE, TRUE
2   The NO quick brown fox ok jumps bye over the l...   TRUE, TRUE

请注意,我知道我可以将3列合并为一列。然而,我想知道上述问题是否可行。
4个回答

4
为什么不将所有功能合并到一个巨大的函数中?
def oneGaintFunc(col):    
    def foo(col):
        if 'hi' in col:
            return 'TRUE'

    def bar(col):
        if 'bye' in col:
            return 'TRUE'

    def baz(col):
        if 'ok' in col:
            return 'TRUE'

    a = foo(col)
    b = bar(col)
    c = baz(col)
    return '{} {} {}'.format(a, b, c)

df['new_col'] = df['col'].apply(oneGiantFunc)

我也知道这个可能性。但是我对前面提到的情况很好奇。谢谢。 - J.Do
1
这不是正确的方式,但对于较小的函数来说仍然是一个好主意。 - Ankit Kumar Namdeo
1
@AnkitKumarNamdeo 是的,我个人不会这样做,但我认为这可能是最直观的解决方案,老实说。 - spicypumpkin

2
您可以使用apply列表推导式一起使用,其中过滤器为None值:
dfs['new_col'] = dfs['col'].apply(lambda x: (', '.join([x for x in 
                                            [foo(x), bar(x), baz(x)] if x != None])))
print (dfs)
                                                 col     new_col
0  The quick hi brown fox hi jumps over the lazy dog        TRUE
1  The quick hi brown fox bye jumps over the lazy...  TRUE, TRUE
2  The NO quick brown fox ok jumps bye over the l...  TRUE, TRUE

1
这取决于你的函数...最好是测试一下。 - jezrael
1
@J. 不,我不认为这比使用组合函数更快。这里有太多步骤:3个函数调用、.join、另一个if语句和apply。 - AsheKetchum

1
我不认为你可以真正地“同时”完成它。但是,这里有两个选项。
1. 假设函数已经定义如下:
dfs['new_col1'] = (dfs['col'].apply(foo)&dfs['col'].apply(bar))&dfs['col'].apply(baz)

2. 重新定义函数

def foo(aao): # all at once
    if ('hi' in col) and ('bye' in col) and ('ok' in col):
        return 'TRUE'

dfs['new_col'] = dfs['col'].apply(aao)

1
使用 lambda 函数,例如:
lambda x: ', '.join([f(x) for f in [foo, bar, baz] if f(x)])

在调用apply时。完整示例:
In : dfs['new_col'] = dfs['col'].apply(lambda x: ', '.join([f(x) for f in [foo, bar, baz] if f(x)]))

In : dfs
Out: 
                                                 col     new_col
0  The quick hi brown fox hi jumps over the lazy dog        TRUE
1  The quick hi brown fox bye jumps over the lazy...  TRUE, TRUE
2  The NO quick brown fox ok jumps bye over the l...  TRUE, TRUE

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接