比较DF中两列的(子)字符串

时间:2018-08-14 08:02:43

标签: python string pandas dataframe

我有一个DF,如下所示:

DF =
id  token      argument1             argument2 
1   Tza        Tuvia Tza             Moscow  
2   perugia    umbria                perugia    
3   associated the associated press  Nelson

我现在想比较列argumentXtoken的值,并相应地为新列ARG选择值。

DF =
id  token      argument1             argument2    ARG
1   Tza        Tuvia Tza             Moscow       ARG1
2   perugia    umbria                perugia      ARG2
3   associated the associated press  Nelson       ARG1

这是我尝试过的:

conditions = [
(DF["token"] == (DF["Argument1"])),
 DF["token"] == (DF["Argument2"])]

choices = ["ARG1", "ARG2"]

DF["ARG"] = np.select(conditions, choices, default=nan)

这仅比较整个String,如果匹配则匹配。诸如.isin.contains之类的构造或使用诸如DF["ARG_cat"] = DF.apply(lambda row: row['token'] in row['argument2'],axis=1)之类的帮助器列均无效。有什么想法吗?

2 个答案:

答案 0 :(得分:2)

str.contains与正则表达式一起使用-jointoken|中的所有值用于正则表达式OR,以检查带有字边界的子字符串:

pat = '|'.join(r"\b{}\b".format(re.escape(x)) for x in DF["token"])
conditions = [ DF["argument1"].str.contains(pat), DF["argument2"].str.contains(pat)]

choices = ["ARG1", "ARG2"]

DF["ARG"] = np.select(conditions, choices, default=np.nan)
print (DF)
   id       token            argument1 argument2   ARG
0   1         Tza            Tuvia Tza    Moscow  ARG1
1   2     perugia               umbria   perugia  ARG2
2   3  associated  the associated ress    Nelson  ARG1

编辑:

如果要比较每一行:

d = {'id': [1, 2, 3], 
     'token': ["Tza","perugia","israel"], 
     "argument1": ["Tuvia Tza","umbria","Tuvia Tza"], 
     "argument2": ["israel","perugia","israel"]} 
DF = pd.DataFrame(data=d) 
print (DF)
   id    token  argument1 argument2
0   1      Tza  Tuvia Tza    israel
1   2  perugia     umbria   perugia
2   3   israel  Tuvia Tza    israel

conditions = [[x[0] in x[1] for x in zip(DF['token'], DF['argument1'])], 
              [x[0] in x[1] for x in zip(DF['token'], DF['argument2'])]]

choices = ["ARG1", "ARG2"]

DF["ARG"] = np.select(conditions, choices, default=np.nan)
print (DF)
   id    token  argument1 argument2   ARG
0   1      Tza  Tuvia Tza    israel  ARG1
1   2  perugia     umbria   perugia  ARG2
2   3   israel  Tuvia Tza    israel  ARG2

答案 1 :(得分:1)

获取布尔值索引

argument_cols = ['argument1', 'argument2']
boolean_idx = DF[argument_cols].apply(
    lambda arg_column: DF['token'].combine(arg_column, lambda token, arg: token in arg)
)

boolean_idx
Out:
id  argument1   argument2
0   True    False
1   False   True
2   True    False

从行中选择值:

selected_vals = DF[argument_cols][boolean_idx]

selected_vals
Out: 
id            argument1  argument2
0             Tuvia Tza        NaN
1                   NaN    perugia
2  the associated press        NaN

堆栈selected_vals并获取包含参数名称的索引级别(如果一行中包含True值的列超过一列,则此代码将失败):

argument_index_level = selected_vals.stack().index.get_level_values(-1)
# Index(['argument1', 'argument2', 'argument1'], dtype='object')

DF['ARG'] = argument_index_level

DF 
Out: 
id             argument1        argument2        token        ARG
0              Tuvia Tza           Moscow          Tza  argument1
1                 umbria          perugia      perugia  argument2
2   the associated press           Nelson   associated  argument1

您可以使用apply()更改“ ARG”列中的值。