@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)
  • Вопрос задан
  • 296 просмотров
Пригласить эксперта
Ответы на вопрос 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'
Ответ написан
Ваш ответ на вопрос

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

Войти через центр авторизации
Похожие вопросы
28 мая 2024, в 08:33
500000 руб./за проект
28 мая 2024, в 07:56
1500 руб./в час
28 мая 2024, в 06:55
400 руб./в час