python - 在应用函数中将数据框列作为参数传递

python - pass dataframe column as argument in apply function

我有以下数据框:

In[1]: df = DataFrame({"A": ['I love cooking','I love rowing'], "B": [['cooking','rowing'],['cooking','rowing']]})

因此我得到的输出是:

In[2]: df
Out[1]: 
            A                  B
0  I love cooking  [cooking, rowing]
1   I love rowing  [cooking, rowing]

我想创建一个 'C' 列,用于计算 'B' 元素在 'A' 中出现的次数。

我创建的函数是:

def count_keywords(x,y):
    a = 0
    for element in y:
        if element in x:
            a += 1
return a

然后做:

df['A'].apply(count_keywords,args=(df['B'],))

在这种情况下,我将整个 pandas 数据系列作为参数传递,因此数据系列 df['B'] 的元素显然是一个列表,而不是一个字符串(这又是列表的元素)。

所以我得到:

TypeError: 'in <string>' requires string as left operand, not list

但是,如果我调整函数使得:

def count_keywords(x,y): 
    a = 0
    for element in y:
        for new_element in element:
            if new_element in x:
                a += 1
    return a

然后做:

In[3]: df['A'].apply(count_keywords,args=(df['B'],))

输出为:

Out[2]: 
0    2
1    2

因为函数循环遍历 pandas 系列中的每个元素,然后循环遍历列表中的每个元素。

我怎样才能让函数只检查每个数据帧行中 df['B'] 系列的元素与 df['A'] 系列元素的对比,所以输出是: ?

Out[2]: 
0    1
1    1

非常感谢!

你必须 apply 在另一个轴上。

def count_keywords(row): 
    counter = 0
    for e in row['B']:
        if e in row['A']:
            counter += 1
    row['C'] = counter
    return row

df2 = df.apply(count_keywords,axis=1)

给你:

           A                B           C
0   I love cooking  [cooking, rowing]   1
1   I love rowing   [cooking, rowing]   1

那么 df2['C'] 应该给你你提到的 1,1 系列。

另一种方法是使用集合交集来计算大小。从理论上讲,这可能比遍历元素更快,因为 set 是为这种事情设计的:

df['C'] = df.apply(lambda x: len(set(x.B).intersection(set(x.A.split()))), axis = 1)