Skip to main content
 首页 » 编程设计

python之Pandas之检查一个数据框中的字符串列是否包含来自另一个数据框的一对字符串

2025年05月04日21oomusou

这个问题是基于我问的另一个问题,我没有完全涵盖这个问题:Pandas - check if a string column contains a pair of strings

这是问题的修改版本。

我有两个数据框:

df1 = pd.DataFrame({'consumption':['squirrel ate apple', 'monkey likes apple',  
                                  'monkey banana gets', 'badger gets banana', 'giraffe eats grass', 'badger apple loves', 'elephant is huge', 'elephant eats banana tree', 'squirrel digs in grass']}) 
 
df2 = pd.DataFrame({'food':['apple', 'apple', 'banana', 'banana'],  
                   'creature':['squirrel', 'badger', 'monkey', 'elephant']}) 

目标是测试 df.food:df.creature 对是否存在于 df1.consumptions 中。

在上面的例子中这个测试的预期答案是:

['True', 'False', 'True', 'False', 'False', 'True', 'False', 'True', 'False'] 

模式是:

squirrel ate apple = True 因为松鼠和苹果是一对。 monkey likes apple = False 因为 monkey 和 apple 不是我们要找的一对。

我正在考虑构建一个包含对值数据帧的字典,其中每个数据帧都对应一个生物,例如松鼠、猴子等,然后使用 np.where 创建一个 bool 表达式并执行 str.contains。

不确定这是否是最简单的方法。

请您参考如下方法:

考虑这种矢量化方法:

from sklearn.feature_extraction.text import CountVectorizer 
 
vect = CountVectorizer() 
 
X = vect.fit_transform(df1.consumption) 
Y = vect.transform(df2.creature + ' ' + df2.food) 
 
res = np.ravel(np.any((X.dot(Y.T) > 1).todense(), axis=1)) 

结果:

In [67]: res 
Out[67]: array([ True, False,  True, False, False,  True, False,  True, False], dtype=bool) 

解释:

In [68]: pd.DataFrame(X.toarray(), columns=vect.get_feature_names()) 
Out[68]: 
   apple  ate  badger  banana  digs  eats  elephant  gets  giraffe  grass  huge  in  is  likes  loves  monkey  squirrel  tree 
0      1    1       0       0     0     0         0     0        0      0     0   0   0      0      0       0         1     0 
1      1    0       0       0     0     0         0     0        0      0     0   0   0      1      0       1         0     0 
2      0    0       0       1     0     0         0     1        0      0     0   0   0      0      0       1         0     0 
3      0    0       1       1     0     0         0     1        0      0     0   0   0      0      0       0         0     0 
4      0    0       0       0     0     1         0     0        1      1     0   0   0      0      0       0         0     0 
5      1    0       1       0     0     0         0     0        0      0     0   0   0      0      1       0         0     0 
6      0    0       0       0     0     0         1     0        0      0     1   0   1      0      0       0         0     0 
7      0    0       0       1     0     1         1     0        0      0     0   0   0      0      0       0         0     1 
8      0    0       0       0     1     0         0     0        0      1     0   1   0      0      0       0         1     0 
 
In [69]: pd.DataFrame(Y.toarray(), columns=vect.get_feature_names()) 
Out[69]: 
   apple  ate  badger  banana  digs  eats  elephant  gets  giraffe  grass  huge  in  is  likes  loves  monkey  squirrel  tree 
0      1    0       0       0     0     0         0     0        0      0     0   0   0      0      0       0         1     0 
1      1    0       1       0     0     0         0     0        0      0     0   0   0      0      0       0         0     0 
2      0    0       0       1     0     0         0     0        0      0     0   0   0      0      0       1         0     0 
3      0    0       0       1     0     0         1     0        0      0     0   0   0      0      0       0         0     0 

更新:

In [92]: df1['match'] = np.ravel(np.any((X.dot(Y.T) > 1).todense(), axis=1)) 
 
In [93]: df1 
Out[93]: 
                 consumption  match 
0         squirrel ate apple   True 
1         monkey likes apple  False 
2         monkey banana gets   True 
3         badger gets banana  False 
4         giraffe eats grass  False 
5         badger apple loves   True 
6           elephant is huge  False 
7  elephant eats banana tree   True 
8     squirrel digs in grass  False 
9        squirrel.eats/apple   True   # <----- NOTE