Логическое сравнение списка подстрок со списком строк - PullRequest
0 голосов
/ 29 мая 2018

У меня есть исследование, но я не нашел ответа на вопрос ниже.

Как я могу выполнить логическое сравнение для списка подстрок в списке строк?

Ниже приведен код:

string = {'strings_1': ['AEAB', 'AC', 'AI'], 
             'strings_2':['BB', 'BA', 'AG'], 
             'strings_3': ['AABD', 'DD', 'PP'], 
             'strings_4': ['AV', 'AB', 'BV']}

df_string = pd.DataFrame(data = string)

substring_list = ['AA', 'AE']

for row in df_string.itertuples(index = False):
    combine_row_str = [row[0], row[1], row[2]]

    #below is the main operation
    print(all(substring in row_str for substring in substring_list for row_str in combine_row_str))

Вывод, который я получаю:

False
False
False

Вывод, который я хочу:

True
False
False

Ответы [ 2 ]

0 голосов
/ 29 мая 2018

Поскольку вы используете pandas, вы можете вызывать apply по строкам и str.contain с регулярным выражением, чтобы найти, соответствуют ли строки.Первый шаг состоит в том, чтобы найти, совпадает ли какое-либо из значений со строками в substring_list:

df_string.apply(lambda x: x.str.contains('|'.join(substring_list)), axis=1)

, это возвращает:

   strings_1  strings_2  strings_3  strings_4
0       True      False       True      False
1      False      False      False      False
2      False      False      False      False

Теперь неясно, хотите ли вы,вернуть true, если обе подстроки присутствуют в строке или только в одной из них.Если только один из них, вы можете просто добавить any () после метода contains ():

df_string.apply(lambda x: x.str.contains('|'.join(substring_list)).any(), axis=1)

, это возвращает:

0     True
1    False
2    False
dtype: bool

Для второго случая jpp предоставляет однострочное решение с объединением элементов строки в одну строку, но, пожалуйста, обратите внимание, что оно не будет работать для угловых случаев, когда у вас есть два элемента подряд, например, «BBA» и «ABB», и вы пытаетесь найти соответствие для «AA».Объединенная строка «BBAABB» все равно будет соответствовать «AA», что неверно.Я хотел бы предложить решение с применением и дополнительной функцией, чтобы код был более читабельным:

def areAllPresent(vals, patterns):
  result = []
  for pat in patterns:
    result.append(any([pat in val for val in vals]))
  return all(result)

df_string.apply(lambda x: areAllPresent(x.values, substring_list), axis=1)

Из-за вашего образца данных он все равно будет возвращать тот же результат, но он работает для случаев, когда сопоставлениенеобходимо и то и другое:

0     True
1    False
2    False
dtype: bool
0 голосов
/ 29 мая 2018

Вот один из способов, используя pd.DataFrame.sum и понимание списка:

df = pd.DataFrame(data=string)

lst = ['AA', 'AE']

df['test'] = [all(val in i for val in lst) for i in df.sum(axis=1)]

print(df)

  strings_1 strings_2 strings_3 strings_4   test
0      AEAB        BB      AABD        AV   True
1        AC        BA        DD        AB  False
2        AI        AG        PP        BV  False
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...