comparer des chaînes, si l'enregistrement de la trame de données correspond une fois, puis passez à la ligne suivante
J'ai un dataframe comme ceci:
df = pd.DataFrame({'item_descrip': ['ebc root beer single',
'yic yac big pack freshmint',
'froggy jumbo flakes',
'jumbo tart warmer',
'beer jerky'
]
})
J'ai une liste comme celle-ci:
brand_list = ['ebc', 'yic yac', 'beer', 'jumbo', 'tart', 'froggy']
Je veux faire correspondre les chaînes de la brand_list
avec les chaînes de la item_descrip
colonne et supprimer les correspondances dans la item_descrip
colonne. Je souhaite créer une autre colonne unbranded
contenant les chaînes nettoyées de item_descrip
.
Mon problème est que j'ai un très grand brand_list
et que certaines des chaînes de cette liste correspondent plusieurs fois dans la item_descrip
colonne. Ma sortie souhaitée est si une correspondance est déjà trouvée pour une ligne, sautez cette ligne.
Sortie désirée:
| | 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 |
C'est le code qui fonctionne pour supprimer les correspondances, mais il supprime toutes les correspondances dans la item_descrip
colonne. Par exemple, dans mon brand_list
j'ai ebc
et beer
dans la liste. Pour le premier enregistrement, je veux seulement ebc
être supprimé et non beer
depuis qu'un match a déjà été fait. Si une correspondance est faite sur la première partie de la chaîne, ne traitez plus cet enregistrement et passez à la suivante.
Donc, fondamentalement, il semble qu'une instruction if puisse entrer dans la compréhension de la liste, mais je ne suis pas sûr de savoir comment écrire quelque chose qui dit: si la correspondance est acceptée, sinon continuez à chercher.
df['unbranded'] = [' '.join([y for y in x.split() if not y.startswith(tuple(brand_list))]) for x in df['item_descrip']]
J'ai tiré le meilleur parti de ce one-liner ici: https://stackoverflow.com/questions/51666374/how-to-remove-strings-present-in-a-list-from-a-column-in-pandas
Réponses
AVERTISSEMENT: je suis l'auteur de trrex
Si vous vous souciez des performances, utilisez 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)
Production
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
La fonction make construira un trie regex . Pour mieux comprendre ce qui se passe, make génère l'expression régulière suivante:
\b(?:froggy|tart|beer|yic yac|jumbo|ebc)\b
L'argument n = 1, signifie que le motif ne sera remplacé qu'une seule fois, d'après la documentation :
n int, par défaut -1 (tous)
Number of replacements to make from start.