compare strings, se o registro do dataframe corresponder uma vez, continue na próxima linha
Eu tenho um dataframe assim:
df = pd.DataFrame({'item_descrip': ['ebc root beer single',
'yic yac big pack freshmint',
'froggy jumbo flakes',
'jumbo tart warmer',
'beer jerky'
]
})
Eu tenho uma lista assim:
brand_list = ['ebc', 'yic yac', 'beer', 'jumbo', 'tart', 'froggy']
Eu quero combinar strings no brand_list
com as strings na item_descrip
coluna e remover as correspondências na item_descrip
coluna. Quero criar outra coluna unbranded
que contém as strings limpas de item_descrip
.
Meu problema é que tenho um muito grande brand_list
e algumas das cadeias de caracteres desta lista estão combinando várias vezes na item_descrip
coluna. Minha saída desejada é se uma correspondência já for encontrada para uma linha, então pule essa linha.
Saída desejada:
| | item_descrip | unbranded |
|---:|:-----------------------------------|:-----------------------------------|
| 0 | ebc root beer single | root beer single |
| 1 | yic yac big pack freshmint singles | big pack freshmint singles |
| 2 | froggy jumbo flakes | jumbo flakes |
| 3 | jumbo tart warmer | tart warmer |
| 4 | beer jerky | jerky |
Este é o código que funciona para remover correspondências, mas remove todas as correspondências na item_descrip
coluna. Por exemplo, no meu brand_list
tenho ebc
e beer
na lista. Para o primeiro registro, eu só quero ebc
ser removido e não beer
porque uma combinação já foi feita. Se uma correspondência for feita na primeira parte da string, não processe mais esse registro e vá para a próxima.
Então, basicamente, parece que uma instrução if pode entrar na compreensão da lista, mas não tenho certeza de como escrever algo que diga: se correspondido, passe, caso contrário, continue procurando.
df['unbranded'] = [' '.join([y for y in x.split() if not y.startswith(tuple(brand_list))]) for x in df['item_descrip']]
Eu tirei o máximo proveito desta linha aqui: https://stackoverflow.com/questions/51666374/how-to-remove-strings-present-in-a-list-from-a-column-in-pandas
Respostas
AVISO DE RESPONSABILIDADE: Sou o autor de trrex
Se você se preocupa com o desempenho, use trrex :
import pandas as pd
import trrex as tx
df = pd.DataFrame({'item_descrip': ['ebc root beer single',
'yic yac big pack freshmint',
'froggy jumbo flakes',
'jumbo tart warmer',
'beer jerky'
]
})
brand_list = ['ebc', 'yic yac', 'beer', 'jumbo', 'tart', 'froggy']
df['unbranded'] = df['item_descrip'].str.replace(tx.make(brand_list), '', n=1)
print(df)
Resultado
item_descrip unbranded
0 ebc root beer single root beer single
1 yic yac big pack freshmint big pack freshmint
2 froggy jumbo flakes jumbo flakes
3 jumbo tart warmer tart warmer
4 beer jerky jerky
A função make construirá um regex trie . Para entender melhor o que está acontecendo, make gera a seguinte expressão regular:
\b(?:froggy|tart|beer|yic yac|jumbo|ebc)\b
O argumento n = 1, significa que o padrão será substituído apenas uma vez, a partir da documentação :
n int, padrão -1 (todos)
Number of replacements to make from start.