Disons que mon dataframe a une colonne qui est mélangée avec des mots ou des caractères anglais et chinois, je voudrais supprimer tous les espaces entre eux s'ils sont des mots chinois, sinon s'ils sont anglais, gardez un espace uniquement entre les mots:
J'ai trouvé une solution pour supprimer les espaces supplémentaires entre l'anglais d' ici
Out[87]: 0 Very calm 1 Keen and analytical 2 Rash and careless 3 Always joyful 4 ä½ å¥½ 5 é»ç³å ¬å¸ dtype: object
Code:
Out[87]: 0 Very calm 1 Keen and analytical 2 Rash and careless 3 Always joyful 4 ä½ å¥½ 5 é» ç³ å ¬ å¸ dtype: object
En dehors:
regex = re.compile('(?<![a-zA-Z]{2})(?<=[a-zA-Z]{1}) +(?=[a-zA-Z] |.$)') s.str.replace(regex, '')
Mais comme vous le voyez, cela fonctionne pour l'anglais mais n'a pas supprimé les espaces entre le chinois, comment pourrait-on obtenir un résultat attendu comme suit:
import re import pandas as pd s = pd.Series(['V e r y calm', 'Keen and a n a l y t i c a l', 'R a s h and careless', 'Always joyful', 'ä½ å¥½', 'é» ç³ å ¬ å¸', 'FAN STUD1O', 'beauty face åº éº'])
Référence: supprimer tous les espaces entre les mots chinois avec regex
3 Réponses :
Vous pouvez utiliser la propriété Unicode chinoise (enfin, CJK) \p{script=Han}
ou \p{Han}
.
Cependant, cela ne fonctionne que si le moteur regex prend en charge les expressions régulières Unicode UTS # 18. Le module Python re par défaut ne le fait pas, mais vous pouvez utiliser le moteur de regex alternatif (beaucoup amélioré):
Very calm Keen and analytical Rash and careless Always joyful ä½ å¥½ é»ç³å ¬å¸
Résulte en
import regex as re rex = r"(?<![a-zA-Z]{2})(?<=[a-zA-Z]{1})[ ]+(?=[a-zA-Z] |.$)|(?<=\p{Han}) +" test_str = ("V e r y calm\n" "Keen and a n a l y t i c a l\n" "R a s h and careless\n" "Always joyful\n" "ä½ å¥½\n" "é» ç³ å ¬ å¸") result = re.sub(rex, "", test_str, 0, re.MULTILINE | re.UNICODE)
Démo en ligne (la démo utilise PCRE à des fins de démonstration uniquement)
rent_name
votre code à une colonne rent_name
, en utilisant df['rent_name'].replace(re.compile(r"(?<![a-zA-Z]{2})(?<=[a-zA-Z]{1})[ ]+(?=[a-zA-Z] |.$)|(?<=\p{Han}) +", re.MULTILINE | re.UNICODE))
, il renvoie error: bad escape \p
, des idées?
Utilisez-vous import regex as re
?
Oui, cela TypeError: replace() missing 1 required positional argument: 'repl'
une erreur: TypeError: replace() missing 1 required positional argument: 'repl'
. Si test_str
est une colonne dans dataframe, comment puis-je utiliser votre code?
Utilisez des limites de mots \b
pour regarder autour de vous:
['Very calm', 'Keen and analytical', 'Rash and careless', 'Always joyful', 'ä½ å¥½', 'é»ç³å ¬å¸']
Cela correspond aux espaces entre les «caractères de mot» solitaires (délimités par des limites de mots), qui incluent les caractères chinois.
Avant python 3 (et pour java par exemple), \w
ne correspond qu'aux lettres anglaises, vous devrez donc ajouter le drapeau unicode (?u)
au début de l'expression régulière.
s = ['V e r y calm', 'Keen and a n a l y t i c a l', 'R a s h and careless', 'Always joyful', 'ä½ å¥½', 'é» ç³ å ¬ å¸'] regex = r'(?<=\b\w\b) +(?=\b\w\b)' res = [re.sub(regex, '', line) for line in s] print(res)
Production:
(?<=\b\w\b) +(?=\b\w\b)
Comment pourrais-je votre code pour la colonne s
dans dataframe?
Pourquoi avez-vous besoin de (?u)
? Il est activé par défaut dans Python 3.x.
@ WiktorStribiżew Je ne le savais pas. Je suis un novice en python. Réponse simplifiée et note faite sur la version python. Merci
Cette regex devrait vous offrir ce que vous voulez. Voir l'extrait de code complet en bas.
0 Very calm 1 Keen and analytical 2 Rash and careless 3 Always joyful 4 ä½ å¥½ 5 é»ç³å ¬å¸ dtype: object
J'ai apporté les modifications suivantes à votre expression régulière ci-dessus: À l'heure actuelle, l'expression régulière correspond essentiellement à tous les espaces qui apparaissent après un mot d'une seule lettre et avant un autre mot à caractère unique.
[\u4e00-\u9fff]
qui couvrirait également le japonais et le coréen.\s
que nous puissions prendre d' autres entrées comme les onglets.re.UNICODE
afin que \s
couvre également les espaces Unicode.import re import pandas as pd s = pd.Series( [ "V e r y calm", "Keen and a n a l y t i c a l", "R a s h and careless", "Always joyful", "ä½ å¥½", "é» ç³ å ¬ å¸", ] ) regex = re.compile( "((?<![a-zA-Z]{2})(?<=[a-zA-Z]{1})\s+(?=[a-zA-Z]\s|.$)|(?<=[\u4e00-\u9fff]{1})\s+)", re.UNICODE, ) s.str.replace(regex, "")
Production:
regex = re.compile( "((?<![a-zA-Z]{2})(?<=[a-zA-Z]{1})\s+(?=[a-zA-Z]\s|.$)|(?<=[\u4e00-\u9fff]{1})\s+)", re.UNICODE, )
Désolé, votre solution ne semble pas fonctionner pour FAN STUD1O
, je pense que nous devons peut-être df['Day'].str.capitalize()
puis appliquer votre code?
Je gérerais ce cas avec une expression s.str.replace(re.compile("\s+", re.UNICODE), " ")
plus simple qui combine tous les espaces dans une chaîne s.str.replace(re.compile("\s+", re.UNICODE), " ")
Qu'en est-il des mots à une seule lettre
"a"
et"I"
?Merci les gars. Beaucoup de bonnes options.
C'est une bonne question @Bohemian, dans de rares cas, par exemple la
XYZ company
, le seul espace doit être supprimé et obtenir laXYZ company
en fait, mais je ne sais pas comment résoudre ce problème.J'ai mis à jour de nouveaux éléments pour la série
s
, il semble qu'aucun de votre solution de travail comme il mélange de l' anglais et chinois. Quelqu'un pourrait-il aider à tester à nouveau?