Задать вопрос
@Pavel_132131

Как в pandas правильно применить оператор and (&)?

У меня есть множество дата фреймов (в примере их несколько), мне нужно проверить каждый из них на наличие ключевых слов в первом столбце. Для получения нужного дата сета я должен получить два (или более совпадений), в обычной ситуации это решается через оператор 'and', но применить его в pandas не получается (я знаю что в pandas оператор 'and' обозначается как '&').
В тоже время оператор 'or' ('|') прекрасно работает. Но проблема в том что '|' для выполнения условия достаточно хотя бы одного совпадения, а мне нужно несколько.
Я понимаю что с оператором '&' будет проверятся оба условия, которые будут применяться к каждой строке в дата фрейме, я хотел бы узнать можно ли применить условия к целому столбцу и не построчно ?

import pandas as pd
import numpy as np
import re


df_16 = pd.DataFrame({"number": ["onE:    ", "  Two:", np.nan, "fIve", "four@", "tHree", "   one", "tWo", "tWo     SIx", "one"], 'phone': [11, 22, 33, 44, 55, 300, 77, 1000, 1, 5],
 "item": ["debt", "phone", "room", "go", "hoot", "aaple", "orange", "phone", "tool", 'hoooo'],
  "seria": [1050.34344343, 150, 544, 245, 230, 50, 300, 70, 33, 100]},
  index=['q', 'e', 'r', 't', 'u', 'y', 'j', 'v', 'm', 'g'])

df_17 = pd.DataFrame({"number": ["onE#", "tWo:", "six      ", " fiVE   ", "four", "thRee:", np.nan, "twO", "two Six", "Two fOr"], 'phone': [11, 22, 33, 44, 55, 300, 77, 1000, 1, 5],
 "item": ["debt", "phone", "room", "go", "hoot", "aaple", "orange", "phone", "tool", 'hoooo'],
  "seria": [1050.34344343, 160, 544, 245, 230, 50, 300, 70, 33, 100]},
  index=['q', 'e', 'r', 't', 'u', 'y', 'j', 'v', 'm', 'g'])

df_18 = pd.DataFrame({"number": ["gggg", "TTt", "HHHH     ", " HJkl   ", "green", "redd", np.nan, "twO", "nuul", "Null"], 'phone': [11, 22, 33, 44, 55, 300, 77, 1000, 1, 5],
 "item": ["debt", "phone", "room", "go", "hoot", "aaple", "orange", "phone", "tool", 'hoooo'],
  "seria": [1050.34344343, 160, 544, 245, 230, 50, 300, 70, 33, 100]},
  index=['q', 'e', 'r', 't', 'u', 'y', 'j', 'v', 'm', 'g'])

list_data = [df_16, df_17]

for i in list_data:
    i['number'] = i['number'].fillna('empty') # заполняет nan значения 
    i['number'] = i['number'].agg([lambda do: re.sub(r'[#@:]', ' ', do)], axis=0) # убирает ненужные символы
    i['number'] = i['number'].agg([lambda do: re.sub(r'\s+', ' ', do)], axis=0) # убирает двойные (или больше) пробелы
    
    # переводит строк в нижний регистр, убирает пробелы (которые остались), поиск совпадений
    check = (i['number'].astype(str).str.lower().str.strip().str.fullmatch('two (six|for)') & i['number'].astype(str).str.lower().str.strip().str.fullmatch('six')) 
    if check.any():
        getting = i
        print(getting)        
        print(check)


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

import pandas as pd
import numpy as np
import re


df_16 = pd.DataFrame({"number": ["onE:    ", "  Two:", np.nan, "fIve", "four@", "tHree", "   one", "tWo", "tWo     SIx", "one"], 'phone': [11, 22, 33, 44, 55, 300, 77, 1000, 1, 5],
 "item": ["debt", "phone", "room", "go", "hoot", "aaple", "orange", "phone", "tool", 'hoooo'],
  "seria": [1050.34344343, 150, 544, 245, 230, 50, 300, 70, 33, 100]},
  index=['q', 'e', 'r', 't', 'u', 'y', 'j', 'v', 'm', 'g'])

df_17 = pd.DataFrame({"number": ["onE#", "tWo:", "six      ", " fiVE   ", "four", "thRee:", np.nan, "twO", "two Six", "Two fOr"], 'phone': [11, 22, 33, 44, 55, 300, 77, 1000, 1, 5],
 "item": ["debt", "phone", "room", "go", "hoot", "aaple", "orange", "phone", "tool", 'hoooo'],
  "seria": [1050.34344343, 160, 544, 245, 230, 50, 300, 70, 33, 100]},
  index=['q', 'e', 'r', 't', 'u', 'y', 'j', 'v', 'm', 'g'])

df_18 = pd.DataFrame({"number": ["gggg", "TTt", "HHHH     ", " HJkl   ", "green", "redd", np.nan, "twO", "nuul", "Null"], 'phone': [11, 22, 33, 44, 55, 300, 77, 1000, 1, 5],
 "item": ["debt", "phone", "room", "go", "hoot", "aaple", "orange", "phone", "tool", 'hoooo'],
  "seria": [1050.34344343, 160, 544, 245, 230, 50, 300, 70, 33, 100]},
  index=['q', 'e', 'r', 't', 'u', 'y', 'j', 'v', 'm', 'g'])

list_data = [df_16, df_17]

for i in list_data:
    i['number'] = i['number'].fillna('empty') # заполняет nan значения 
    i['number'] = i['number'].agg([lambda do: re.sub(r'[#@:]', ' ', do)], axis=0) # убирает ненужные символы
    i['number'] = i['number'].agg([lambda do: re.sub(r'\s+', ' ', do)], axis=0) # убирает двойные (или больше) пробелы
    
    check = i['number'].astype(str).str.lower().str.strip().str.fullmatch('two (six|for)') # Проверка 1
    check_1 = i['number'].astype(str).str.lower().str.strip().str.fullmatch('six') # Проверка 2
    
    if check.any() and check_1.any():
        print(check)
        print(check_1)
        getting = i
        print(getting)
  • Вопрос задан
  • 324 просмотра
Подписаться 1 Простой Комментировать
Пригласить эксперта
Ответы на вопрос 1
@o5a
Не до конца понятно, почему в проверках разные условия, если по условию требовалось найти более 1 совпадения условия, а не несколько условий?
Вообще check возвращает массив булевых значений, т.е. кол-во совпадений можно найти просто через sum()
check = (i['number'].astype(str).str.lower().str.strip().str.fullmatch('two (six|for)')
print('совпадений:', sum(check))

Если же действительно требовалось совпадение 2-х условий, то они не имеют смысла в таком виде: строка не может одновременно совпадать с 'two (six|for)' и 'for'
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы