У меня есть DF, как показано ниже:
DF =
id token argument1 argument2
1 Tza Tuvia Tza Moscow
2 perugia umbria perugia
3 associated the associated press Nelson
Теперь я хочу сравнить значения столбцов argumentX и token и соответственно выбрать значение для нового столбца 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)
Это сравнивает только всю строку и соответствует, если они идентичны. Такие конструкции, как .isin, .contains или использование вспомогательного столбца, такого как DF["ARG_cat"] = DF.apply(lambda row: row['token'] in row['argument2'],axis=1), не работали. Любые идеи?






Используйте str.contains с регулярным выражением - join все значения в token по | для регулярного выражения 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
Я еще не мог проверить это, но просто подумав о логике регулярного выражения, не всегда ли это возвращает "ARG1"?
@ThelMi - Как ты думаешь, почему? Для второго подходит perugia, поэтому ARG2
Да, в этом случае, но представьте себе DF, например: d = {'id': [1, 2, 3], 'token': ["Tza", "perugia", "israel"], "argument1": ["Tuvia Tza "," umbria "," Tuvia Tza "]," argument2 ": [" israel "," perugia "," israel "]} DF = pd.DataFrame (data = d)
@ThelMi - Не уверен, вы ожидали ARG1 3 раза?
Ожидается: ARG1, ARG2, ARG2. Получено: ARG1, ARG2, ARG1
@ThelMi - я вижу, дай мне секундочку.
Получить логический индекс
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_val в стек и получите уровень индекса, который содержит имена аргументов (этот код завершится ошибкой, если в строке есть более одного столбца, содержащего значение 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
Вы можете изменить значения в столбце «ARG» с помощью apply ().
Это может сработать, но мне нужно экранировать некоторые символы, потому что я получаю действительно раздражающую ошибку регулярного выражения Python "sre_constants.error: нечего повторять", как показано здесь stackoverflow.com/questions/3675144/…