当需要传递 'self' 作为参数时使用 apply 函数

use of apply function when you need to pass 'self' as argument

我有一个 pandas 数据框 df,其中一列是 'keywords',另一列是 'possible keywords',因此前两行如下所示:

df['keywords'][0] = 'traveling'
df['possible keywords'][0] = ['traveling', 'fishing','cooking']

df['keywords'][1] = 'fishing'
df['possible keywords'][0] = ['traveling', 'fishing','cooking']

假设 df['possible keywords'] 系列中的每个元素都包含相同的列表,具有相同的元素(['traveling', 'fishing','cooking'] ).

我想要生成第三列,其中包含不在 'keyword' 列中的 'possible keywords',以便相应的行如下所示:

df['non keywords'][0] = ['fishing','cooking']
df['non keywords'][1] = ['traveling','cooking']

我可以通过以下代码实现:

def establish(X):
    my_list = ['traveling', 'fishing','cooking']
    for element in my_list:
        if element in X:
            my_list.remove(element)
            return my_list

data['non keywords'] = data['keywords'].apply(establish)

但是,我必须将 'possible keywords' 列中的值作为 'my_list' 包含在建立函数中。

如何将 'possible keywords' 中的值作为参数传递给建立函数?

这是我目前尝试的问题:

新版本建立功能:

def establish(my_list,X):
    for element in my_list:
        if element in X:
            my_list.remove(element)
            return my_list

my_list = ['traveling', 'fishing','cooking']
data['non keywords'] = data['keywords'].apply(establish(my_list))

Traceback (most recent call last):
  File "C:\Users\xxx\Anaconda3\lib\site-    packages\IPython\core\interactiveshell.py", line 3035, in run_code
    exec(code_obj, self.user_global_ns, self.user_ns)
  File "<ipython-input-21-859ebaa71600>", line 1, in <module>
    data['non keywords'] = data['keywords'].apply(establish(my_list))
TypeError: establish() missing 1 required positional argument: 'X'

如果我改为尝试:

data['non keywords'] = data['keywords'].apply(establish(my_list,data['keywords']))

问题是:

Traceback (most recent call last):
  File "C:\Users\xxx\Anaconda3\lib\site-    packages\IPython\core\interactiveshell.py", line 3035, in run_code
    exec(code_obj, self.user_global_ns, self.user_ns)
  File "<ipython-input-22-ee891e061f5a>", line 1, in <module>
    data['non keywords'] =     data['original_keyword'].apply(establish(my_list,data['keywords']))
  File "C:\Users\xxxx\Anaconda3\lib\site-packages\pandas\core\series.py", line 2058, in apply
    mapped = lib.map_infer(values, f, convert=convert_dtype)
  File "pandas\src\inference.pyx", line 1046, in pandas.lib.map_infer    (pandas\lib.c:56983)
TypeError: 'NoneType' object is not callable

非常感谢您的帮助!

apply() 方法需要一个函数或其他可调用函数作为参数,这正是您在传递 establish 时在第一个示例中传递的内容。在内部,pandas 依次调用您将指定列的每个条目作为参数传递的函数。

直接调用 establish(my_list) 将无法正常工作,因为您的函数现在需要 2 个参数。

调用establish(my_list,data['keywords'])是一个"valid"函数调用,但是会return None而且第二个参数的参数类型错误,因为establish 需要一个条目而不是一列。一旦它 returns None,这就是实际传递给 apply() 函数的内容,这显然是不可调用的,因此 pandas 抛出。

一个解决方案是创建一个辅助函数,该函数 "pre-bakes" 您的第一个参数并将第二个参数作为其唯一参数,然后用它调用 establish() 函数,这样您就可以通过apply() 方法的第二个函数。一种方便的方法是使用 functools.partial:

import functools
my_list = ['traveling', 'fishing','cooking']
helper_func = functools.partial(establish, my_list) # note that helper_func is an actual function that you can call
data['non keywords'] = data['keywords'].apply(helper_func)