Python Pandas-检查一个数据帧中的字符串列是否包含另一个数据帧中的一对字符串

Python Pandas-检查一个数据帧中的字符串列是否包含另一个数据帧中的一对字符串,python,pandas,string-matching,boolean-expression,Python,Pandas,String Matching,Boolean Expression,这个问题是基于我问的另一个问题,我没有完全涵盖这个问题: 这是问题的一个修改版本 我有两个数据帧: df1 = pd.DataFrame({'consumption':['squirrel ate apple', 'monkey likes apple', 'monkey banana gets', 'badger gets banana', 'giraffe eats grass', 'badger apple loves'

这个问题是基于我问的另一个问题,我没有完全涵盖这个问题:

这是问题的一个修改版本

我有两个数据帧:

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']})
目标是测试df1.consumptions中是否存在df.food:df.Biome对

上述示例中该测试的预期答案为:

['True', 'False', 'True', 'False', 'False', 'True', 'False', 'True', 'False']
模式是:

松鼠吃苹果=正确,因为松鼠和苹果是一对。 猴子喜欢苹果=错,因为猴子和苹果不是我们要找的一对

我正在考虑构建一个成对值的数据帧字典,其中每个数据帧将用于一种生物,例如松鼠、猴子等,然后使用np.where创建布尔表达式并执行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
[92]中的
df1['match']=np.ravel(np.any((X.dot(Y.T)>1.todense(),axis=1))
In[93]:df1
出[93]:
消费匹配
0松鼠吃了苹果真的吗
猴子喜欢假苹果
猴子香蕉成真
獾得到香蕉是假的
长颈鹿吃草是假的
5獾苹果爱真
大象是巨大的假象
大象吃香蕉树真的吗
8只松鼠在草地上挖洞

9 squirrel.eats/apple True#考虑这种矢量化方法:

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
[92]中的
df1['match']=np.ravel(np.any((X.dot(Y.T)>1.todense(),axis=1))
In[93]:df1
出[93]:
消费匹配
0松鼠吃了苹果真的吗
猴子喜欢假苹果
猴子香蕉成真
獾得到香蕉是假的
长颈鹿吃草是假的
5獾苹果爱真
大象是巨大的假象
大象吃香蕉树真的吗
8只松鼠在草地上挖洞

9 squirrel.eats/apple True#这是我用理解和
zip

注意,这将检查
df1

c = df1.consumption.values.tolist()
f = df2.food.values.tolist()
a = df2.creature.values.tolist() 

check = np.array([[fd in cs and cr in cs for fd, cr in zip(f, a)] for cs in c])

check.any(1)

array([ True, False,  True, False, False,  True, False,  True, False], dtype=bool)

这是@MaxU的
pandas
版本。尊重他的所作所为。。。太棒了

X = df1.consumption.str.get_dummies(' ')
Y = (df2.creature + ' ' + df2.food).str.get_dummies(' ') \
    .reindex_axis(X.columns, 1, fill_value=0)

# This is where you can see which rows from `df2` (columns)
# matched with which rows from `df1` (rows) 
XY = X.dot(Y.T)

print(XY)

   0  1  2  3
0  2  1  0  0
1  1  1  1  0
2  0  0  2  1
3  0  1  1  1
4  0  0  0  0
5  1  2  0  0
6  0  0  0  1
7  0  0  1  2
8  1  0  0  0

# return the desired `True`s and `False`s

XY.gt(1).any(1)

0     True
1    False
2     True
3    False
4    False
5     True
6    False
7     True
8    False
dtype: bool

天真测试


这是我用理解和
zip

注意,这将检查
df1

c = df1.consumption.values.tolist()
f = df2.food.values.tolist()
a = df2.creature.values.tolist() 

check = np.array([[fd in cs and cr in cs for fd, cr in zip(f, a)] for cs in c])

check.any(1)

array([ True, False,  True, False, False,  True, False,  True, False], dtype=bool)

这是@MaxU的
pandas
版本。尊重他的所作所为。。。太棒了

X = df1.consumption.str.get_dummies(' ')
Y = (df2.creature + ' ' + df2.food).str.get_dummies(' ') \
    .reindex_axis(X.columns, 1, fill_value=0)

# This is where you can see which rows from `df2` (columns)
# matched with which rows from `df1` (rows) 
XY = X.dot(Y.T)

print(XY)

   0  1  2  3
0  2  1  0  0
1  1  1  1  0
2  0  0  2  1
3  0  1  1  1
4  0  0  0  0
5  1  2  0  0
6  0  0  0  1
7  0  0  1  2
8  1  0  0  0

# return the desired `True`s and `False`s

XY.gt(1).any(1)

0     True
1    False
2     True
3    False
4    False
5     True
6    False
7     True
8    False
dtype: bool

天真测试


谢谢-有一个警告-生物和食物的出现没有固定的模式。因此:
Y=vect.transform(df2.biote+''+df2.food)
不起作用。抱歉,我刚刚修改了问题中的消耗值以反映这一点。@vagabond,您是否根据修改后的数据集测试了我的解决方案?;-)哇!它起作用了!有没有办法从匹配的行中提取生物和食物?我的查找数据也是100K++行。稀疏矩阵可能会消耗内存?@vagabond,稀疏矩阵非常节省内存(这是它们的主要用途)。关于提取-你能打开一个新问题并在那里做一个例子吗?嗯,是的,我可以-另一个问题是,有时文本没有空格-squirrel.eats/apple。这是URL数据。谢谢-有一个警告-生物和食物的出现没有固定的模式。因此:
Y=vect.transform(df2.biote+''+df2.food)
不起作用。抱歉,我刚刚修改了问题中的消耗值以反映这一点。@vagabond,您是否根据修改后的数据集测试了我的解决方案?;-)哇!它起作用了!有没有办法从匹配的行中提取生物和食物?我的查找数据也是100K++行。稀疏矩阵可能会消耗内存?@vagabond,稀疏矩阵非常节省内存(这是它们的主要用途)。关于提取-你能打开一个新问题并在那里做一个例子吗?嗯,是的,我可以-另一个问题是,有时文本没有空格-squirrel.eats/apple。这是URL数据。