Un DataFrame pandas contient une colonne avec des descriptions et des espaces réservés entre accolades:

descr                        replacement
This: {should be replaced}   with this

La tâche consiste à remplacer le texte entre les accolades par du texte provenant d'une autre colonne de la même ligne. Ce n'est malheureusement pas aussi simple que:

df["descr"] = df["descr"].str.replace(r"{*?}", df["replacement"])

~/anaconda3/lib/python3.6/site-packages/pandas/core/strings.py in replace(self, pat, repl, n, case, flags, regex)
   2532     def replace(self, pat, repl, n=-1, case=None, flags=0, regex=True):
   2533         result = str_replace(self._parent, pat, repl, n=n, case=case,
-> 2534                              flags=flags, regex=regex)
   2535         return self._wrap_result(result)
   2536 

~/anaconda3/lib/python3.6/site-packages/pandas/core/strings.py in str_replace(arr, pat, repl, n, case, flags, regex)
    548     # Check whether repl is valid (GH 13438, GH 15055)
    549     if not (is_string_like(repl) or callable(repl)):
--> 550         raise TypeError("repl must be a string or callable")
    551 
    552     is_compiled_re = is_re(pat)

TypeError: repl must be a string or callable
4
clstaudt 17 mars 2019 à 16:36

2 réponses

Meilleure réponse

Votre code utilise le Pandas.Series .str.replace() et il attend deux chaînes pour effectuer l'opération de remplacement, mais le deuxième paramètre est une série.

Series.str.replace(pat, repl, n=-1, case=None, flags=0, regex=True)[source]

Remplacez les occurrences de pattern/regex dans la série/l'index par une autre chaîne. Équivalent à str.replace() ou re.sub(). Paramètres:

pat : chaîne ou regex compilé

repl : chaîne ou appelable ...

Vous pouvez le corriger en utilisant directement le Pandas.Series Méthode .replace() :

df = pd.DataFrame({'descr': ['This: {should be replaced}'],
                   'replacement': 'with this'
                  })
>> df["descr"].replace(r"{.+?}", df["replacement"], regex = True)
0    This: with this

Observation:

J'ai changé un peu votre regexp.

4
Community 20 juin 2020 à 09:12

Utilisez la compréhension de liste avec re.sub, surtout si les performances sont importantes:

import re

df['new'] = [re.sub(r"{.*?}", b, a) for a, b in zip(df['descr'], df['replacement'])]
print (df)
                        descr replacement              new
0  This: {should be replaced}   with this  This: with this
1                This: {data}         aaa        This: aaa
4
jezrael 17 mars 2019 à 14:02