Voici la colonne que j'ai, je veux diviser en clé-valeur et stocker dans une nouvelle colonne dans pandas df.
{"FontStyle"=>"Gill Sans Standard", "FontSize"=>"Medium (3mm)"}
{"Font Style"=>"Gill Sans Standard","Font Size"=>"Medium (3mm)"}
{"Font Style":"Script","Font Size":"Medium (3mm)"}
{"Font Style"=>"Gill Sans Standard","Font Size"=>"Medium (3mm)"}
{"Font Style":"Gill Sans Standard","Font Size":"Medium (3mm)"}
Le principal problème est que certains d'entre eux ont '= > 'alors que certains ont deux points
Je veux deux nouvelles colonnes dans df, une pour le style de police et une autre pour la taille de la police et les valeurs respectées qu'elles contiennent
si quelqu'un peut m'aider à y parvenir, alors ce serait génial, et aussi si vous pouviez me recommander un livre / tutoriel pour regex qui serait super.
Merci
3 Réponses :
Je pense que regex ici n'est pas nécessaire, utilisez:
d = {'=>':':', 'FontSize':'Font Size','FontStyle':'Font Style'}
regex = '|'.join(r"{}".format(x) for x in d.keys())
df1 = (df['col'].dropna()
.str.replace(regex, lambda x: d[x.group()], regex=True)
.apply(ast.literal_eval))
df2 = pd.DataFrame(df1.values.tolist())[['Font Size','Font Style']].dropna(how='all')
print (df2)
Font Size Font Style
0 Medium (3mm) Gill Sans Standard
1 Medium (3mm) Gill Sans Standard
2 Medium (3mm) Script
3 Medium (3mm) Gill Sans Standard
4 Medium (3mm) Gill Sans Standard
import ast
print (df)
col
0 {"FontStyle"=>"Gill Sans Standard", "FontSize"...
1 {"Font Style"=>"Gill Sans Standard","Font Size...
2 {"Font Style":"Script","Font Size":"Medium (3m...
3 {"Font Style"=>"Gill Sans Standard","Font Size...
4 {"Font Style":"Gill Sans Standard","Font Size"...
5 NaN
Explication :
DataFrame.dropna Series.str.replace pour les valeurs du dictionnaire ast.literal_eval NaN Je reçois ce message d'erreur `nœud ou chaîne malformé: nan`
il y a 145 valeurs nulles dans cette colonne
la solution fonctionne bien, existe-t-il un moyen de fusionner ces colonnes en seulement 2? et oui, nous devons supprimer les valeurs nan
@Vijayaraghavan - Il suffit de voir qu'il y a un remplacement multiple nécessaire, donc la réponse a été modifiée.
Ce n'est de loin pas le code le plus efficace mais cela ferait le travail.
Font Size Font Style 0 Medium (3mm) Gill Sans Standard 1 Medium (3mm) Gill Sans Standard 2 Medium (3mm) Script 3 Medium (3mm) Gill Sans Standard
Le résultat du code ci-dessus:
import pandas as pd
import ast
text = '''{"FontStyle"=>"Gill Sans Standard", "FontSize"=>"Medium (3mm)"}
{"Font Style"=>"Gill Sans Standard","Font Size"=>"Medium (3mm)"}
{"Font Style"=>"Script","Font Size"=>"Medium (3mm)"}
{"Font Style"=>"Gill Sans Standard","Font Size"=>"Medium (3mm)"}'''
my_list = []
text = text.replace("FontStyle", "Font Style")
text = text.replace("FontSize", "Font Size")
text = text.replace("=>", ":")
text = text.split("\n")
for one_dict in text:
my_list.append(ast.literal_eval(one_dict))
df = pd.DataFrame(my_list)
print(df)
J'espère que cela aide. :-) Faites-moi savoir si c'est le cas.
Essayez ceci:
import ast
df['col'] = df['col'].str.replace('=>', ': ').str.replace('FontSize', 'Font Size').str.replace('FontStyle', 'Font Style')
df['col']= df["col"].apply(lambda x : dict(ast.literal_eval(x)))
df1 = df['col'].apply(pd.Series)
Pouvez-vous me dire pourquoi ne pas utiliser eval?
Quel est votre résultat requis, pouvez-vous le mentionner également?