удалить элемент из списка, если он не соответствует подстроке, независимо от форматирования - PullRequest
1 голос
/ 06 апреля 2020

У меня есть следующий фрейм данных:

df = pd.DataFrame()
df['full_string'] = [['apples and bananas', 'applesandbananasamongstothers', 'something else'], 
          ['ApplesandBananas', 'apples and Bananas', 'bananas']]
df['substring'] = ['apples and bananas', 'apples and bananas']

Желаемый результат - сохранить элементы в df ['full_string'], которые содержат текст, который находится в df ['substring'], при этом учтите, что:

  • регистр, прописные или строчные буквы не должны иметь значения
  • интервал между словами
  • слова могут содержать другой текст, не относящийся к текст в df ['substring']

Желаемый результат:

df['outcome'] = [['apples and bananas', 'applesandbananasamongstothers'], 
      ['ApplesandBananas', 'apples and Bananas', 'bananas']]

Я попытался получить первое ключевое слово df ['substring'], чтобы использовать его как совпадение с df ['full_string'], однако, это не позволило мне сохранить элемент 'bananas' во второй строке фрейма данных.

( Это плохо работает с фиктивной данные ):

first_keyword = []
for i in df['substring']:
    first_keyword.append(i.split(' ', 1)[0])

df['first_keyword'] = first_keyword

df['C'] = [x[0].lower() in (x[1].lower()) for x in zip(df['first_keyword'], df['full_string'])]

1 Ответ

1 голос
/ 06 апреля 2020

Чтобы упростить пример, я решил работать со списком, содержащим ваши фиктивные данные. Вам нужно будет адаптировать его к вашей проблеме. Более того, я интерпретирую ваше предложение «Желаемый результат - сохранить элементы в df ['full_string'], содержащие текст, который находится в df ['substring']", как text = word.

full_str = ['apples and bananas', 'applesandbananasamongstothers', 'something else', 
           'ApplesandBananas', 'apples and Bananas', 'bananas']
sub_str = ['apples and bananas', 'red and blue']

# Extract words from sub strings
words_in_sub = [elt.split() for elt in sub_str]
# Flatten and remove duplicates
words_in_sub = list(set([item for sublist in words_in_sub for item in sublist]))

# Init output
output = list()
# Loop on the strings in full string
for full_s in full_str:
    # Loop on the words to look for
    for word in words_in_sub:
        if word.lower() in full_s.lower():
            output.append(full_s)
            break

Вывод:

In: output
Out: 
['apples and bananas',
 'applesandbananasamongstothers',
 'ApplesandBananas',
 'apples and Bananas',
 'bananas']

В верхнем / нижнем регистре выполняется условие if. Интервал учитывается оператором in. О наличии другого текста в full_s заботится оператор in. Оператор in возвращает True, если слово присутствует где-то в строке. Единственный случай, когда он вернет False, в то время как слово может рассматриваться как присутствующее в строке, - это если слово сокращается до двух пробелом, например 'bana naan dapp les'. Этот пример не будет сохранен в списке вывода.

РЕДАКТИРОВАТЬ: С несколькими строками. Вы также можете просто сгладить список и использовать первый код.

full_str = [['apples and bananas', 'applesandbananasamongstothers', 'something else'], 
            ['ApplesandBananas', 'apples and Bananas', 'bananas']]
sub_str = [['apples and bananas'], ['apples and bananas']]

# Assuming same number of rows between full_str and sub_str
# And you want to keep element of full_str[k] according to sub strings in sub_str[k]
number_of_rows = len(full_str)
for k in range(number_of_rows):
    # Extract words from sub strings
    words_in_sub = [elt.split() for elt in sub_str[k]]
    # Flatten and remove duplicates
    words_in_sub = list(set([item for sublist in words_in_sub for item in sublist]))

    # Init output
    output = list()
    # Loop on the strings in full string
    for full_s in full_str[k]:
        # Loop on the words to look for
        for word in words_in_sub:
            if word.lower() in full_s.lower():
                output.append(full_s)
                break
...