как проверить соответствие каждой буквы в строке строки

#python #pandas #dataframe

#питон #панды #фрейм данных

Вопрос:

У меня есть подмножество фрейма данных

 df = pd.DataFrame(  {  'id': ['1001','1002','1003','1004','1005','1006','1007','1008','1009','1010'],  'colA': ['H','L B','L H','L B','L S B','B','B S L','L B S','L S B','L S B'],  'colB': ['H','L|B','H|L','H|L','L|S|B','L|S|B','L|S|B','L|S|B','L|S','L']  }  )  

Я провожу сравнение уровня строк для этого фрейма данных. Я хочу проверить , совпадают ли все буквы в row['colA'] со всеми буквами в row['colB'] , независимо от того, в каком порядке они появляются, и игнорируя | colB ввод . Это логика для функции, но она работает не так, как предполагалось, и как мне обновить ее, чтобы игнорировать |

 def match_or_not(df):  for index,row in df.iterrows():  if row['colA'] == row['colB']:  print ("Match for " str(row['id']))  else:  print ("Not match for " str(row['id']))    

Мне нужна помощь, чтобы обновить условие после if ключевого слова в приведенной выше функции, как я могу написать, чтобы получить желаемый результат. Случаи, для которых он должен совпадать и не совпадать, показаны на рисунке:

введите описание изображения здесь

Ответ №1:

Должно сработать следующее:

 def match_or_not(df):  for index,row in df.iterrows():  #First make a list out of the values, then compare the sorted values  if sorted(row['colA'].split(" ")) == (sorted(row['colB'].split("|"))):  print ("Match for " str(row['id']))  else:  print ("Not match for " str(row['id']))  

Ответ №2:

Вы можете использовать метод «split()» для строк, а также наборов, например:

 def match_or_not(df):  for index,row in df.iterrows():  a_set = set(row['colA'].split(" "))  b_set = set(row['colB'].split("|"))  if a_set == b_set:  print ("Match for " str(row['id']))  else:  print ("Not match for " str(row['id']))  

split() создает список подстрок, используя заданный разделитель (в вашем случае пробел и a | ).

set() делает этот список набором. Наборы легко сравнивать, так как порядок в них не имеет значения. Однако это решение имеет потенциальный недостаток, который не отражен в данных вашего примера:

 set("L L".split(" "))  

Это разбивает строку L L , которая создает список из двух строк «L». Однако элементы набора уникальны, поэтому он преобразуется в набор {'L'} (имейте в виду только один L.)

Поэтому, если ожидается, что ваши данные будут содержать такие двойные строки и их появление должно совпадать по количеству, этого решения недостаточно.

Ответ №3:

Вы можете использовать df.apply без df.iterrows() :

 gt;gt;gt; df.apply(lambda row: f"Match for {row['id']}" if set(row['colA'].replace(" ", "")) == set(row['colB'].replace("|", "")) else f"No match for {row['id']}", axis=1) 0 Match for 1001 1 Match for 1002 2 Match for 1003 3 No match for 1004 4 Match for 1005 5 No match for 1006 6 Match for 1007 7 Match for 1008 8 No match for 1009 9 No match for 1010  

set(row['colA'].replace(" ", "")) == set(row['colB'].replace("|", "")) Условие гарантирует, что все символы, кроме пробелов из colA , существуют в colB (кроме | символов, все пробелы и каналы удаляются перед преобразованием в a set ).

Комментарии:

1. Извините, но для этого не требуется, метод all() проверяет, все ли элементы A содержатся в B, а не совпадают ли два столбца. Но df подать заявку-это определенно правильный путь!

2. @AchilleG Вы правы, я пропустил часть, чтобы убедиться, что у них обоих одинаковые символы. Я немного изменил решение set , теперь оно дает ожидаемый результат. На самом деле изображение операционной системы отличается от предоставленных данных.