Как создать маску подстрок, используя np.where или понимание списков? - PullRequest
1 голос
/ 12 июля 2020

У меня есть два python списка строк, которые я хотел бы сравнить. Первый - это мой основной список, содержащий серию длинных кодов. Второй - это список неполных строк.

input:
list1 = ['fda3232', 'fcg3224', 'kgj5543', '3323fda9832', 'ffz3392', '221gks9483', 'mnx8385', 'aaz9323', '332kgj4323'] 

list2 = ['fda', 'kgj', 'mxx', 'mnx']

Желаемый результат - маска списка 1, заполненная подстроками из списка два. Если совпадений не найдено, list3 может вернуть 0, np.nan, '-' или аналогичные. Другими словами, я ищу следующее:

output: 

list3 = ['fda', np.nan, 'kgj', 'fda', np.nan, np.nan, 'mnx', np.nan, 'kgj']

С помощью людей из другого треда я смог приблизиться. Однако эти результаты возвращают значения в списке 1, но я хотел бы, чтобы мой результат возвращал соответствующую подстроку из списка 2.

solution 1: 
list3 = [x if any(y in x for y in list2) else np.nan for x in list1]

solution 2:
list3 = np.where([np.sum(np.char.find(x, sub=list2)+1) for x in list1], list1, np.NaN) 

Ответы [ 3 ]

2 голосов
/ 12 июля 2020

Вы можете использовать:

import numpy as np

list1 = ['fda3232', 'fcg3224', 'kgj5543', '3323fda9832', 'ffz3392', '221gks9483', 'mnx8385', 'aaz9323', '332kgj4323']

list2 = ['fda', 'kgj', 'mxx', 'mnx']

def isin(haystack):
    for needle in list2:
        if needle in haystack:
            return needle
    return np.nan

list3 = [isin(haystack) for haystack in list1]
print(list3)

Что дает

['fda', nan, 'kgj', 'fda', nan, nan, 'mnx', nan, 'kgj']

Вы можете даже выразить это в понимании:

list3 = [result[0]
         for haystack in list1
         for result in [[needle for needle in list2 if needle in haystack] or [np.nan]]]
0 голосов
/ 12 июля 2020

Посмотрите, работает ли это. Logi c - это подавить все цифры в list1, чтобы получить код и посмотреть, находится ли этот код в list2. Если да, добавьте код, иначе любой другой заполнитель, например - или nan.

list3 = []
for item in list1:
    code = re.sub(r'[0-9]+', '', item)
    if code in list2:
        list3.append(code)
    else:
        list3.append(np.nan)

print(list3)

Вывод:

['fda', nan, 'kgj', 'fda', nan, nan, 'mnx', nan, 'kgj']
0 голосов
/ 12 июля 2020

Эта функция вернет сравниваемый список. Он проверяет, находится ли substring в main string, если это True, список x добавляется. После того, как одна подстрока закончена, if statement проверяет, было ли совпадение. Если он добавляет его, если нет, он добавляет None значение

list1 = ['fda3232', 'fcg3224', 'kgj5543', '3323fda9832', 'ffz3392', '221gks9483', 'mnx8385', 'aaz9323', '332kgj4323'] 
list2 = ['fda', 'kgj', 'mxx', 'mnx']

def chan(list1, list2):
    for i in list1:
        x = []
        for j in list2:
            if j in i:
                x.append(j)
        if len(x) > 0:
            lister.append(''.join(x))
        else:
            lister.append(None)
    return lister
print(chan(list1, list2))
...